2014-02-18 151 views
0

的影响我有以下四大类问题:Java继承和覆盖方法 - 改性

class X { 
    void a() { 
     b(); 
     c(); 
    } 
    void b() { 
     System.out.println("b from class X"); 
    } 
    private void c() { 
     System.out.println("c from class X"); 
    } 
} 

class Y extends X {  
    void b() { 
     System.out.println("b from class Y"); 
    } 
} 

class Z extends Y {  
    void b() { 
     System.out.println("b from class Z"); 
    } 
    void c() { 
     System.out.println("c from class Z"); 
    }  
} 


public class Main { 

    public static void main(String[] args) { 
     Y y = new Z(); 
     y.a(); 
    } 

} 

请不要评论类的合理性,它只是一个例子。我也尝试通过使用eclipse调试器的方法来跟踪JVM的流程,但是通过这些方法的步骤在某些点上有点快。

我已经有了,那

Y y = new Z(); 

创建在Z类的新实例,并将其分配给Y类的参考。由于Z中没有构造函数,因此编译器会在每个超类中查找是否存在构造函数,如果没有构造函数,则使用该对象类的构造函数。 此后,

y.a(); 

方法被调用。在类Z中没有这样的方法,所以我们再次结束于方法a存在的类X并执行它。 首先我们执行该方法c中调用后使用它,因为你的目标是Z类的一个实例,并且该方法B在Z类覆盖导致输出

b from class Z. 

方法B(在方法) 。由于我们的实例仍然从Z类的实例,并存在在这个类中的方法c您能想出的想法,输出

c from class Z 

会发生。但这不是真的,因为类X中的c方法是一种私有方法。由于它是私有的,它不能被继承到子类(它甚至不能被看到)。所以不需要任何从X继承的类也有c方法。是不是真的,因为从方法a调用c导致在类X中调用c方法而不是在类Z中调用?

所以简述: 是我从上面的解释正确还是缺少什​​么?我只是有点糊涂了,虽然我的实例是从类Z,从里面方法导致以下结果调用方法C:

b from class Z 
c from class X 

我的第一个想法是,输出的样子:

b from class Z 
c from class Z 

希望我以某种方式现在可以帮助我的方式描述问题。谢谢你的回复。

+0

注意:你说,“编译器在每个超类中查找是否存在构造函数”。所有这些类都有构造函数。如果源代码中没有一个,编译器将生成一个默认的无参数构造函数,该构造函数仅调用超类构造函数。 –

回答

1

这是事实,这将是印:

c from class X 

因为cprivateX,和private methods aren't inherited in Java

子类不继承其父类的私有成员。但是,如果超类具有访问其专用字段的公共或受保护方法,那么这些也可以由子类使用。

因此,即使X的方法a调用c方法,它只能调用Xc方法。在Z中存在另一种称为c的方法并不重要; a只能拨打X中的c方法。 c方法Z确实不是覆盖c方法X,因为它是私人的。

要调用Zc方法的唯一方法是有一个Z引用并直接调用它,因为它不是私有的。

Z z = new Z(); 
z.c(); 

,它将打印

c from class Z 
+0

好的,太好了。感谢您的快速回答。 – ROT13

0

是的你是对的。类X在方法的():从类X

void a() { 
    b(); 
    c(); 
} 

仅方法C()是可见的。这是因为从X班内部看不到Z班。

0

编译器可以静态解析C()其德X类中的私有方法,没有必要动态清晰度,这意味着没有多态私人方法的行为。

认为c()是实现一个()的一部分,它的一个实现细节,想象一下你在X中将名称从c改为c1,你期望改变一个不同的行为私人方法名称在一个类?,语言必须确保这样的变化不会对孩子有影响。