首页 > 编程知识 正文

关于继承的说法正确的是超类,超类代表的对象比子类多

时间:2023-05-05 21:42:30 阅读:163214 作者:626

主要是了解一些概念,开发语言思想来自现实世界。

员工-产品经理、程序员、PL、BA等是员工。

is-a关系是继承的明显特征。

extends是派生关键字,继承的类称为超类-superclass、基类-base class或父类parent class。

派生的类称为子类subclass、派生类-derived class或子类-child class。

超类基本上定义了公共部分,但子类具有更丰富的功能。

package com.wht.demo; import java.util.Calendar; import java.util.Date; /** *员工类* * @ author wht */public class employee { privatedatehirday; 私有字符串名称; 私有双销售额; publicemployee(stringname,double salary,int year,int month,int day ) { calendar calendar=calendar.getinstance }; Calendar.set(year,month,day ); this.name=name; this.salary=salary; this.hirDay=calendar.getTime (; } public Date getHirDay () { return hirDay; } public String getName () { return name; } public double getSalary () { return salary; } publicvoidraisesalary (double percent ) this.salary=this.salary * percent/100; }} package com.wht.demo; /** *经理继承和员工*/publicclassmanagerextendsemployee { privatedoublebonus; //经理有奖金publicmanager(stringname,double salary,int year,int month,int day,double bonus ) super ) name,salary } @ overridepublicdoublegetsalary ((return super.getsalary ) ) this.bonus-) (super.get salary ) this.bonus-5000 system.out.println(a.getSalary ) ); } public double getBonus () { return bonus; } publicvoidsetbonus (double bonus ) { this.bonus=bonus; } }在}} Java中,继承是单个继承,只能有一个父类,并且可以有多个子类。

子类可以在继承父类的属性和方法时扩展自己的属性和方法。

继承父类时,父类必须具有无参结构。

生成子类时,将使用缺省super )调用父类的生成方法。 初始化子类时,首先调用父类的默认结构,然后调用子类的结构。

要调用父类的属性或方法,请使用super关键字。

调用子类的方法时,首先在子类中查找该方法,找到后调用成功。 否则,我就去找我想在父类中调用的方法。 如果在子类中找到该方法,子类将重写父类的方法。

不能继承由final限定的类。 此外,也不能继承构造方法设置为专用的类。

的私有属性(可以在set get或super方法中使用父类的私有属性)不能继承

无法继承生成方法

super与this关键字

super不是对对象的引用,不能将super指派给对象变量。 它只是指示编译器调用超类方法的关键字。

this指的是所属的对方。

子类可以覆盖父类的方法、类实现方法的个性化。

如上所述获得工资的方法,经理有奖金。

publicstaticvoidmain (string [ ] args ) employeea=newmanager )、20000、2019、10、22,5000.00; system.out.println(a.getSalary ) ); a=new Employe

e("JK",20000,2019,10,22); System.out.println(a.getSalary()); } 继承层次

java继承是单继承,但是可以多层次。A继承B,B又继承C,说白了就是子子孙孙的关系。

多态

一个对象变量可以引用多种实际类型的现象,被称为多态–polymorphism。

动态绑定

在运行时能够自动地选择调用哪个方法的现象称为动态绑定–dynamic binding。
这个就需要理解虚拟机了,方法表–method table机制。

编译器查看对象的声明类型和方法名。编译器将查看调用方法时提供的参数类型。如果是private方法、static方法、final方法或者构造器,那么编译器将可以准确地知道调用哪个方法–静态绑定。运行时虚拟机会调用方法所引用对象的实际类型最合适的那个方法。
先找本类,找不到找父类,搜索消耗开销,虚拟机预先会建立方法表。 阻止继承:final类和方法

不允许扩展的类称为final类。

final类中的所有方法会自动的称为final方法,但是不包括域。

因为不能被继承,自然也不会被覆盖。

强制类型转换

强转目的是暂时忽视对象的实际类型后,使用对象的全部功能。
但是强转有风险,最好先做检测。

public static void main(String[] args) { Employee staff = new Manager("JK",20000,2019,10,22,5000.00); if(staff instanceof Manager){ Manager manager = (Manager)staff; System.out.println(manager.getSalary()); } } 只能在继承层次内进行类型转换。在将超类转换成子类之前,应该使用instanceof进行检测。

真实项目使用场景是:
可能出于多态的考虑,我们往往用父类定义变量,但是我们要使用真实子类特有方法时,就需要向下强行转换。
例如我们很多API返回值的是Object类型,可能我们想要的是List所以需要强行转换后才能继续处理业务逻辑。

抽象类

抽象类很抽象,它是架构常用工具,本身不具备任何可使用的功能,只是用来做定义。
abstract
抽象方法充当着站位的角色,他们的具体时间实现在子类中。

具有抽象方法的类,必须是抽象类。类即使不包含抽象方法,也可以声明为抽象类。抽象类也可以有实例域,并且可以包含具体方法。抽象类不能被实例化。
抽象类用来做定义的,如果可以new对象就没意义了。
class是模板 抽象类说白了就是模板的架构图。

非常灵活的定义,让人无语。
但是通过上面的限制可以知道,继承了抽象类后,抽象方法必须全部实现才是可用的类,否则还是抽象类,等子类全部实现抽象方法后,才能真实创建对象,具体的使用。

真实项目之所以很少使用抽象类是因为很多真实项目习惯的面向接口编程。

受保护的访问

真实项目,印象中一次也没用过。
我们常常把实例域设置为private,然后方法public共享。
这样,即使是子类也不能直接访问父类的实例域。
但是如果想让父类定义的实例域直接共享给子类,而其他类不可见,实例域可以设置为proteced。

其实不建议这么用,因为一旦那天做了修改,你就要告知所有实现这个类的人去修改,这样不符合OOP提倡的数据封闭原则。

Object: 所有类的超类

这是java语言设计思想的核心,既然想从顶往下做设计,必然做一个顶Object类,这样所有的设计才 不会散乱。
Object 默认为所有类的超类,说白了所有定义的类,默认的有个extends Object。

所以有必要了解Object类的所有服务。

换句话说,所有对象都可以用Object类型来接收。

注意
基本类型不是对象。
所有的数组类型,不管是对象数组还是基本类型的数组都扩展于Object。
为什么会这么设计?
有机会可以去了解下底层原来,而出现这种现象可定是有原因的。
这个世界,都会有特例,才能更加高效。

Equals方法

检测两个对象是否相等,说白了就是比对两个变量是不是指向同一个对象。
这种比较在实际业务中没有什么意义。
所以,往往我们需要重写equals方法,因为业务往往是为了比较对象的属性是否相等。

@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Employee employee = (Employee) o; return Double.compare(employee.salary, salary) == 0 && Objects.equals(name, employee.name); } @Override public int hashCode() { return Objects.hash(name, salary); }

如果加上入职时间,怎么比较都不会相等了。
这里面的this就很有意思了

相等测试与继承

java语言规范equals方法要有以下特性:

自反性:对于任何非空引用x,x.equals(x) 应该返回true。对称性:对于任何引用x和y,当且仅当y.equals(x)返回true,x.equals(y)也应该返回true。传递性:对于任何引用x,y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true。一致性:如果x和y引用的对象没有发生变化,反复调用x.equals(y)应该返回相同的结果。对于任意非空x,x.equals(null)应该返回false。

显示工作中,基本没有这个基础知识,很像大学中的一些背下来的规则,真实工作中只是作为一个经验或者习惯管存在了。
核心只需要知道真实开发,对象是否相等是经常需要的,注意null问题,并且知道对象需要重写equals方法。

HashCode方法

这个是伴随着equals方法,并且往往一起出现。
散列码–hash code 是由对象导出的一个整型值。

public static void main(String[] args) { String a ="中国"; System.out.println(a.hashCode()); String b ="中国"; System.out.println(b.hashCode()); }

这两个打印出来散列码一致。
暂时不研究这么深,只需要知道所有对象都有个父类Object,Object中的方法每个对象都会继承下来。
HashCode是Object顶层设计的一个核心方法,大约可以理解为,java一切皆对象,每个对象都有个算法生成一个ID。

生产使用规则,Equals方法与hashCode的定义必须一致。
如果重写了equals方法就必须重写hashcode方法。
通过idea编程,可以用快捷键直接快速生成。

ToString方法

和上面两个方法一样,也是任何Object非常常用的方法。
其中+连接直接就调用toString方法,只有是现实的标签,还是能看得懂的字符串,取决于定义方式。
其中idea可以用快捷键直接插入toString方法。

Employee employee = new Employee("JK",20000,2019,10,22); System.out.println(employee);

打印结果:com.wht.demo.Employee@40d4aaa0
类名@地址

对象种重写toString方法

@Override public String toString() { return "Employee{" + "hirDay=" + hirDay + ", name='" + name + ''' + ", salary=" + salary + '}'; }

打印结果为:
Employee{hirDay=Fri Nov 22 19:22:42 CST 2019, name=‘JK’, salary=20000.0}
toString日志常用,业务日志要了解的业务值而非看不懂的地址。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。