超类的一个引用变量可以被任何从该超类派生的子类的引用赋值。你将发现继承的这个方面在很多条件下是很有用的。例如,考虑下面的程序:
class RefDemo {
public static void main(String args[]) {
BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37);
Box plainbox = new Box();
double vol;
vol = weightbox.volume();
System.out.println("Volume of weightbox is " + vol);
System.out.println("Weight of weightbox is " +
weightbox.weight);
System.out.println();
// assign BoxWeight reference to Box reference
plainbox = weightbox;
vol = plainbox.volume(); // OK, volume() defined in Box
System.out.println("Volume of plainbox is " + vol);
/* The following statement is invalid because plainbox
does not define a weight member. */
// System.out.println("Weight of plainbox is " + plainbox.weight);
}
}
这里,weightbox是BoxWeight对象的一个引用,plainbox是Box对象的一个引用。既然BoxWeight是Box的一个子类,允许用一个weightbox对象的引用给plainbox赋值。
理解是引用变量的类型——而不是引用对象的类型——决定了什么成员可以被访问。
也就是说,当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分。这是为什么plainbox不能访问weight的原因,甚至是它引用了一个BoxWeight对象也不行。
仔细想一想,这是有道理的,因为超类不知道子类增加的属性。这就是本程序中的最后一行被注释掉的原因。
Box的引用访问weight域是不可能的,因为它没有定义。尽管前面部分看起来有一点深奥,它是很重要的实际应用。