为什么这个类型化的变量调用子类的函数?

时间:2017-05-06 02:21:08

标签: java casting

我下面有四节课。

课堂笔记:

public class Note {

    Pitch primaryPitch = new Pitch();
    static Pitch secondaryPitch = new Pitch();

    Note() {
        System.out.println("Tune()");
    }
    static void pitch() {
        System.out.println("Note.pitch()");
    }
    void volume() {
        System.out.println("Note.volume()");
    }
}

Class Tune:

public class Tune extends Note{

    Tune()  {  
        System.out.println("Tune()");  
    }

    static void pitch()  {  
        System.out.println("Tune.pitch()");  
    }

    void volume()  {  
        System.out.println("Tune.volume()");  
    }

    void rhythm() 
    {
        Note note = (Note) this;
        note.volume(); 
    }
}

班级歌曲:

public class Song extends Tune{

    void volume()  {  
        System.out.println("Song.volume()");  
        }
    }

班级考试:

public class Test {

    public static void main(String[] args) {

            Note note2 = new Song();
            ((Tune)note2).rhythm();
}

当我运行main时,我期望输出Note.volume()。我期望输出的原因是因为在Tune类中,当我调用note.volume();时,注意已经对一个Note对象进行了类型转换,所以我希望使用Note类的volume()方法调用。相反,我得到Song.volume(),这意味着我正在使用Song类volume()方法调用。

我的问题是,为什么我会Song.volume()而不是note.volume();

2 个答案:

答案 0 :(得分:3)

因为note是Song()类型的对象。将其强制转换为父类型的事实不会更改volume()方法的多态行为。如果您在IDE中运行代码,并且在Tune.Rhythm()中,请查看变量值,这很明显:

enter image description here

答案 1 :(得分:1)

this表示当前实例 Song,即使您投放到Note,它仍然是Song实例

  顺便说一句,在运行时, Java 没有类型,因此运行时中的cast毫无意义。 cast仅从Compiler开始按上下文推断类型。

Song extends Note来自extends Tune来自Override, 以及volume this.volume()方法,因此Override会调用Song.volume parent方法。

如果需要拨打Note.volume班级super,则需要使用volume方法super.volume(),例如:{{1}}。