知识回顾8、继承和多态的问题2
2012-03-19 16:52
197 查看
二、访问成员变量和成员方法的问题
1、第一个例子class Base
{
private int i=2;
public Base()
{
System.out.println(this.getClass());
System.out.println(this.i);
this.display();
//this.sub();
}
public void display()
{
System.out.println("父类的方法");
System.out.println(i);
}
}
class Drib extends Base
{
private int i=22;
public Drib()
{
i=222;
}
public void display()
{
System.out.println("子类的方法");
System.out.println(i);
}
public void sub()
{
}
}
public class Test6
{
public static void main(String[] args)
{
new Drib();
}
}
输出结果是
class test.Drib
2
子类的方法
0
结果为什么是这样的奇怪。
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重写,那么调用自己的
如果是父类的方法被子类重写了,调用子类的
如是是子类独有的方法和变量,父类不能调用
相关文章推荐
- 知识回顾7、继承和多态的问题1
- 知识回顾9、继承和多态的问题3
- Java基础知识回顾之三 ----- 封装、继承和多态
- DELPHI中关于类的继承和多态问题
- 剖析java中的多态(继承)问题
- 基础回顾:get方法和set方法(类的继承多态)
- 关于C++中私有继承后虚函数的访问权限与私有继承后多态的问题
- 知识回顾(二)--继承、抽象
- Java基础知识小计 二,JAVA的三大特性【封装,继承,多态】
- java基础知识回顾之java Thread类学习(七)--java多线程安全问题(死锁)
- 面向对象基础知识(5)- 封装 继承 多态
- 知识回顾(二)--继承、抽象
- 2015-10-12 OC语言中的多态 以及面向对象方法和继承的相关问题总结
- 继承的相关知识以及多态的概念及理解
- Java基础知识:面向对象-封装、继承、多态
- java中静态属性和和静态方法的继承问题以及多态的实质
- C/C++一些知识4(重载与多态、虚继承)
- 汽车鸣笛问题(继承与多态)
- 深入剖析C++继承,多态以及隐藏(三)(类层次中的转化问题)
- Java基础知识-9、对象继承和多态