2009-08-28 70 views
12

我有两个问题在此代码混淆“重写一个私有方法”

public class Override { 
    private void f() { 
     System.out.println("private f()"); 
    } 
    public static void main(String[] args) { 
     Override po = new Derived(); 
     po.f(); 
    } 
} 

class Derived extends Override { 
    public void f() { 
     System.out.println("public f()"); 
    } 
} 

/* 
* Output: private f() 
*/// :~ 

1)如何是函数f是对覆盖PO的参考可见;

2)为什么是输出的 “私人f()的”

+0

但是如何与子类的一个对象可以调用一个超类的一个私有方法的参考???这是一个错误? – 2009-08-28 13:56:10

+0

不,这不是一个错误,这完全是因为它应该工作。 – Jesper 2009-08-29 05:56:37

+0

但不违反这个继承的规则和后期绑定 – 2009-08-29 08:00:56

回答

24
  1. main方法是内部Override类,所以它ofcourse可以看到Override类的私有成员。

  2. 您在Derived覆盖方法f,没有多态性。变量类型po的是Override,因此将需要方法fOverride类。

注意,在Override类方法f是完全不可见的Derived类。在Derived类中的方法f是一种不同的方法,不具有任何与超类中的方法f

+0

但是,当绑定在运行时完成,然后将PO具有派生类对象它是那么如何能够调用父类的私有方法。 – 2009-08-28 11:40:05

+3

无处在你的代码中有一个超类的私有方法的调用。当你调用po.f()时,Override的f被调用,因为po的编译时类型是Override。由于没有压倒一切的,没有动态绑定(无多态性) - Java不看在运行时类型。 – Jesper 2009-08-29 05:54:26

2
Override po = new Derived(); 
po.f(); 

您正在访问即使对象导出,因为按照范围规则,类的私有成员首先考虑,并作为其写在覆盖它引用的私有的F范围覆盖自己的方法,并因为它的私有它根本不在Derived类中覆盖,所以只有方法签名相同时才会覆盖。

Derived po = new Derived(); 
po.f(); 

Thsi是正确的代码,将调用派生公司的F

+0

问题是关于Java,而不是C#。 Java中不存在'虚拟'。 – Jesper 2009-08-28 10:59:21

+0

感谢您的评论,我也修复了answwer。 – 2009-08-28 11:06:16

0

方法的重写有三个conditions.child类必须具有相同的名称和参数和返回值作为超级class.But如果同时满足参数和返回值有所不同,所以倍率是不存在的,即使两个方法是不同的方法确定这样的:!!!

public class Parent { 
      public int addV(int a,int b){ 
     int s; 
     s = a + b; 
     return s; 
    } 
} 

class Child extends Parent{ 
    public void addV(){ 
     //do...something 
    } 
} 

Eclipse将不会说话的错误!因为类Child中的方法addV与父类中的方法addV不同。

+0

只有方法的名称和参数列表必须完全相同。孩子的返回值可以是父母返回值的子类。并且还有两条规则被省略。孩子的方法必须至少与父母方法一样可用。而子类不能抛出新的检查异常或更广泛的异常。 – pkkoniec 2016-10-21 17:48:30