1.扩展类的构造器
扩展类的构造器必须通过隐式地或显式地调用其超类的构造器,将继承而来的字段的构造工作委托给超类。可以使用super来显式地调用超类的某个构造器。如果扩展类构造器的第一条可执行语句不是调用超类构造器的语句,那么扩展类的构造方法会自动调用超类的无参构造器。也就是说,扩展类构造器的第一条语句被认为是如下语句:super();。如果超类没有无参构造器,就必须显式地调用其他构造器。
创建一个(扩展类)对象的过程:为对象的所有字段分配存储空间并初始化为各自类型的默认值。此后,构造过程分为三个阶段。1.调用超类的构造器;2.初始化继承而来的相应的字段;3.执行构造器其他语句。(先进行超类的初始化部分,然后执行超类的构造器,在进行扩展类的初始化部分,最后执行扩展类的构造器。)。
2.类的加载顺序
Java虚拟机先加载超类,再加载扩展类。加载类时,会对静态初始化块、静态成员进行一次初始化。只有要创建一个对象时,才会初始化非静态部分以及构造器(顺序是先父后子),如果只访问静态方法,虚拟机不会加载这些部分。
3.隐藏与覆盖
如果你在扩展类中声明了一个与超类中的某个字段同名的字段,那么虽然超类中继承来的这个字段仍然存在,但是通过它的简单名已经无法直接访问它,必须通过使用super或者超类类型的一个引用来访问它,这种现象是字段的隐藏。
class SuperShow {
public String str = "SuperStr";
public void show() {
System.out.println("Super.show: " + str);
}
}
class ExtendShow extends SuperShow {
public String str = "ExtendStr";
public void show() {
System.out.println("Extend.show: " + str);
}
}
public class hidden {
public static void main(String[] args) {
ExtendShow ext = new ExtendShow();
SuperShow sup = ext;
sup.show();
ext.show();
System.out.println("sup.str = " + sup.str);
System.out.println("ext.str = " + ext.str);
}
}
对于方法,具体应调用哪个版本是由对象的实际类型而不是引用的类型决定的。对于字段,具体应访问哪个类的字段由引用的类型决定,不是由对象的实际类型决定。在一个方法内部,对一个字段的引用总是会引用到在声明这个方法的类中所声明的字段上。
类的静态成员(无论是字段还是方法)不可以被覆盖,只会被隐藏。静态成员的访问是由引用类型决定而不是对象的实际类型。
在类的所有非静态方法中都可以使用super关键字。它将当前对象引用为其超类的一个实例。
class Base {
protected String name() {
return "Base";
}
}
classMore {
protected String name() {
return "More";
}
}
protected void printName() {
Base sref = (Base) this;
System.out.println("this.name(): " + this.name());
System.out.println("sref.name(): " + sref.name());
System.out.println("super.name(): " + super.name());
}
}
super会忽略对象的真正类型而使用超类的name()实现。sref和this行为相同,会基于对象的实际类型来选择name()的实现。
this.name() = More
sref.name() = More
super.name() = Base
4.Object类
Object类是整个类层次结构树的根,定义了大量可以被所有对象继承的方法,这些方法分为两类:通用方法和支持线程的方法。常用的方法是equals()(返回boolean型结果),hashCode()(返回int型结果),clone()方法(返回Object型结果)。Object.equals()中任何两个不同的对象都是不等价的(一个对象只和自身等价),散列码也是不同的。所以我们自己的类通常需要重写实现这两个方法。创建一个可克隆类的最简单的方法是声明它实现了Cloneable接口,并且通过将clone()方法重新声明为公共的来覆盖它:
public class MyClass extends HerClass implements Cloneable {
public MyClass clone() throws CloneNotSupportException {
return (Myclass)super.clone();
}
//...
}