int count = 2;
public void display(){
System.out.println("Base==="+this.count);
}
}
class Derived extends Base{
int count = 20;
@Override
public void display(){
System.out.println("Derived==="+this.count);
}
}
public class FieldAndMethodTest {
public static void main(String args[]){
//1.
System.out.print("a.===="+b.count+"=====");
b.display();
//2.
System.out.print("b.===="+bd.count+"=====");
bd.display();
//3.
System.out.print("c.====="+d.count+"=====");
d.display();
//4.
System.out.print("d.======"+b2d.count+"=====");
b2d.display();
}
}
该输出结果为:
a.====2=====Base===2
b.====2=====Derived===20c.=====20=====Derived===20
d.======2=====Derived===20
结论:对于1、2的输出结果很简单,这里不想解释,对于3:直接通过db访问count实例变量,输出的将是Base(声明时的类型)对象的count实例变量的值,如果db来调用display()方法,该方法表现出Derived(运行时类型)对象的行为方式,所以java继承中对成员变量和方法的处理时不同的,子类重写父类方法,会彻底覆盖了父类的同名方法,但是即使子类定义了与父类完全同名的实例变量,这个实例变量依然不可能覆盖父类定义的实例变量;对于4:直接将d变量赋给d2b变量的类型是Base,这意味着d2b和d两个变量指向同一个Java对象,因此如果在程序中判断d2b==d 将返回true,但是d.count输出20,d2b.count却输出2,两个指向同一个对象的变量,分别访问它们的实例变量时却输出不同的值,这表明在d2b.d变量所指向的java对象中包含了两块内存,分别存放值为2的count实例变量和值为20的count的实例变量。
所以,可得出一下这个结论:
对于一个引用型的变量(bd)而言,当通过该变量访问它所引用的对象的实例变量(如count)时,该实例变量的值取决于声明该变量时的类型;当通过该变量来调用它所引用的对象的方法时,该方法行为取决于它所实际引用的对象的类型.
看了李刚的《疯狂java:突破程序员基本功的16课》后有感