多态转换
子类的每个对象也是超类的对象,程序中出现超类对象的任何地方都可以使用子类对象替换,换句话说,声明为超类的变量可以引用子类的 象,声明为存储超类的数组可以存储子类的对象,但是声明为超类的,无法调用其子类的方法或者变量.
数组转换规则
在Java中,一个超类数组允许被转换成其子类的数组
Manager[] mangers=new Manager[10];
Employee[] staff=mangers;
这与多态间的转换类似,Employee数组中的存储对象无法调用Manger中的内容
子类构造器
由于父类的构造器不能访问其子类的私有字段,所以必须通过一个构造器来初始化这些私有字段,可以利用特殊的super语法调用这个构造器,其使用方法类似于在父类中使用this构造构造器
如果子类的构造器没有显式的调用父类的构造器,将自动调用超类的无参数构造器,如果父类没有无参数的构造器,并且在子类的构造器中又没有显式的调用父类的其它构造器,Java编译器就会报告一个错误
强制类型转换
Java程序设计语言为强制类型转换提供了一种特殊的表示法
double x=3.405;
int nx =(int) x;
同时,也可以对一个对象使用强制类型转换
Employee staff=new Employee[3];
Manager boss=(Manager) stafff[1];
进行该种强制类型转换的唯一原因便是,它可以将子类数组中引用成父类对象的变量复原成子类对象
综上所述,如果将一个子类引用赋给父类变量,编译器是允许的,如果将一个父类的引用赋给一个子类变量的话,这时候就需要用到强制类型转换了
抽象类
使用关键字abstract定义抽象类或抽象方法,具有一个或多个抽象方法的类必须被定义为抽象类
抽象方法充当着占位方法的角色,他们在子类中允许被实现,在子类中,如果仍有一部分抽象方法没有被定义,那么,该子类也必须被定义为抽象的
抽象类不能实例化,如果将一个类声明为abstract,就不能创建这个类的对象,而只能创建这个类子类的对象
var people =new Person[2];
people[0]=new Employee(...);
people[1]=new Student(...);
for (Person p;people)
System.out.println(p.getname()+","+p.getDesciption);
这里,getDesciption在Person类中是一个抽象方法,虽然不能构造抽象类中的对象,但是Person类的变量可以引用其子类的对象,而其子类中定义了getDesciption方法,但是,如果省略了Person类中的抽象方法,就不能在变量p上调用getDesciption方法了
访问控制修饰符
- private-仅对本类可见
- public-对外部完全可见
- projected-对本包和所有子类可见
- 默认-对本包可见
Object类
Object类是所有类的始祖,在Java中每个类中都扩展了Object
equals()
Object类中的equals方法用于检测一个对象与另一个对象是否相等,检测原理为检测两个对象中的所有变量是否相等
在子类中定义equals方法时,首先调用父类的equals,如果检测失败,对象就不可能相等,如果超类中的字段都相同,再比较子类中的实例字段
public boolean equals(Object otherObject)
{
if(!super.equals(otherObject)) return false;
Manager other =(Manager) otherObject;
return bonue==other.bonus;
}
具体参见文章 如何编写一个完美的equals()方法
hashcode()
返回对象的散列码,散列码可以是任意的整数,包括正数和负数,两个相等的对象要求返回相等的散列码
默认的hashcode方法是根据对象的存储地址导出的,这就意味着即使两个对象的字段都相同,但是返回的是不同的散列码
一般来说,因为两个相等的对象㤇反向两个相等我的散列码,所以需要要判断两个对象是否相等,而这个功能是由equals()函数实现的,所以如果你在子类中重新定义了equals函数,就需要在子类中重新定义hashcode方法
toString()
返回表示该对象值的字符串,要在自定义的类中覆盖这个方法,只要一个对象与一个字符串使用+号连接,编译器就会自动调用toString方法来或者这个对象的字符串描述
getClass()
返回包含对象信息的类对象