2016-02-04 40 views
0

我正在学习Java,我对此感到困惑:这段代码究竟工作得如何?类延伸另一个问题?

class A 
{ 
    int n = 9; 

    void show() 
    { 
     System.out.println(n); 
    } 
} 

class B extends A 
{ 
    void show() 
    { 
     System.out.println(n+" "+super.n+" "+a.n); 
    } 

    int n = 4; 
    static A a = new A(); 

    public static void main(String[] args) 
    { 
     B b = new B(); 
     a.show();//9, expected 
     a = b; 
     /*Line A*/ a.show();//4 9 9 
     /*Line B*/ b.show();//4 9 9 
    } 
} 

在A行中,来自B的函数将被调用,这是预期的。但为什么要打印4 9 9?

+0

请参阅[Java关于多态性的教程](https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)。 – rgettman

回答

2

在线路

a = b; 

静态变量a设为B类的实例。这是可能的,因为B继承自A

因此,请从B类中调用方法show(),而不是A

欲了解更多的信息,搜索material on Polymorphism

2

您将b置于a中,但b始终保留为背景中的对象B Class

可以print.out它是这样的:

/*Line B*/ b.show();//4 9 9 
System.out.println(a.getClass()); 

基准是从A类型,但对堆的对象是相同的对象b

1

在A行中,我们实际上调用方法.show()上的class A类型的引用。这里class Bclass A的一个子类。在Java中,父类引用可以指向一个子类对象。

当JVM看到这个调用时,它实际上检查引用实际指向的对象。在我们的例子中,它指向一个class B类型的子类对象。在这里,show方法也在class B中声明。这意味着,它正在成功覆盖父方法。当JVM看到它时,它实际上调用了子类方法而不是父类方法。整个过程称为polymorphism