您的位置:首页 > 其它

知识回顾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重写,那么调用自己的

如果是父类的方法被子类重写了,调用子类的

如是是子类独有的方法和变量,父类不能调用

      
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  class string