1、第一个例子
输出结果是
class test.Drib结果为什么是这样的奇怪。
this.getClass()返回Drib类,可是为什么调用的this.i是
分析一下程序的执行过程:
首先是new Drib();,初始化它之前,先要初始化父类。
那么,父类的int i=2;先初始化了,在执行父类的构造器,因为父类的构造器中有
System.out.println(this.getClass());
System.out.println(this.i);
this.display();
//this.sub();
这几句代码,那么就依次执行,可是从输出结果看来却很奇怪:
this.getClass()返回Drib类,说明this代表的是Drib类的this,
那么,为什么this.i调用的是父类的i,输出为2
为什么this.display()调用子类的display()
为什么this.sub()不能通过编译。
这个this,到底代表的是谁?
答案是,这个this是代表子类的对象没错,但是它却是一个父类的引用。
如果上面的答案你看的很糊涂,那么看下面的这个简单的例子,,从这个直接点的例子中就可以找到上面的答案
2、第2个例子
public class Test7
{
public static void main(String[] args)
{
Demo1 d1=new Demo2();
System.out.println(d1.getClass());
d1.show1();
d1.display();
//d1.show2();
((Demo2)d1).show2();
System.out.println(d1.a);
System.out.println(((Demo2)d1).a);
}
}
class Demo1
{
int a=2;
public void show1()
{
System.out.println("父类的show1");
}
public void display()
{
System.out.println("父类的display");
}
}
class Demo2 extends Demo1
{
int a=3;
public void show1()
{
System.out.println("子类的show1");
}
public void show2()
{
System.out.println("子类的show2");
}
}
在这里,我们new了一个子类Demo2的对象,确实用的父类的引用。
然后执行
System.out.println(d1.getClass());结果表明这是个Demo2的对象,这说明,虽然我们用的是父类的引用,可是这实际上是一个子类的对象。你是否想到了什么,
没错就如同第一例子的this一样,虽然他是子类的this,但是引用确实父类的。
在看d1.show1();这里执行的是谁的show1();答案是子类的,为什么是父类的引用,执行的是子类的show1(),这是因为父类的show1()被子类所覆盖了。这就是为什么上个例子中为什么执行的是子类的display() 一样。
在看 d1.display();因为子类中没有重写display,所以调用父类的display().
再看 //d1.show2();这句话不能通过编译,因为这是一个父类的引用,而父类根本没有show2()的方法,所以不能引用,这就是上个例子中this.sub()不能通过的一样的原因。
要想调用子类的show2(),就只能先强转一下,((Demo2)d1).show2();
再看System.out.println(d1.a);,输出的结果是2,是父类的a=2;
他娘的,方法被覆盖了,调用方法的时候,是调用子类的方法;变量也覆盖了,为什么调用的又是父类的变量?
是不是很纠结,其实,继承关系中,方法是可以被完全覆盖,但是变量不会被覆盖,只是你找不到这个变量的引用而已。
在看下面一段很简单的代码
Demo2 d2=new Demo2();
((Demo1)d2).show1();
System.out.println(((Demo1)d2).a);
你会发现,就算你强转一下d2,调用的依然是子类的show1,但是调用的变量确实父类的了。
这就说明,父类方法确实在继承的过程完全覆盖了,但父类变量却只是失去了引用,当你给他这个引用的时候,就可以调用父类的变量了。(个人理解)
System.out.println(d1.a);输出的是父类的2;
在看
System.out.println(((Demo2)d1).a);
将d1强转一下,那么引用又变成子类的了,这样结果又变成了3。
所以,在调用的问题中记住几点:
(1)、自己的引用可以调用自己的成员变量和成员方法
(2)、子类的引用不能引用父类的对象
(3)、父类的引用可以引用子类的对象,但是该引用调用的所有变量都是自身的变量
调用的方法:
如果是父类的方法并且没有被ilei重写,那么调用自己的
如果是父类的方法被子类重写了,调用子类的
如是是子类独有的方法和变量,父类不能调用