【问题标题】:Confusing "override a private method"令人困惑的“覆盖私有方法”
【发布时间】:2010-11-23 16:34:29
【问题描述】:

我对此代码有两个问题

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 如何在 Override po 的引用上可见;

2) 为什么输出“private f()”

【问题讨论】:

  • 但是子类对象的引用如何调用超类的私有方法???这是一个错误???
  • 不,这不是错误,这正是它应该工作的。
  • 但这不是违反继承和后期绑定的规则

标签: java overriding private


【解决方案1】:
  1. main方法在Override类内部,所以当然可以看到Override类的私有成员。

  2. 没有覆盖fDerived中的方法,不存在多态性。变量po的类型是Override,所以它会采用Override类的方法f

请注意,Override 类中的方法 fDerived 类中根本不可见。 Derived 类中的方法 f 是一个不同的方法,它与超类中的方法 f 没有任何关系。

【讨论】:

  • 但是当绑定在运行时完成时,po 将拥有 Derived 类的对象,因此它如何能够调用超类的私有方法。
  • 代码中没有任何地方调用超类的私有方法。当你调用 po.f() 时,会调用 Override 的 f,因为 po 的编译时类型是 Override。由于没有覆盖,也就没有动态绑定(没有多态性)——Java 不会在运行时查看类型。
【解决方案2】:
Override po = new Derived();
po.f();

即使对象是派生的,您也正在访问 Override 自己的方法,因为根据范围规则,首先考虑类的私有成员,并且正如它在 Override 范围内所写的那样,它引用了私有 f,并且由于它的私有它根本没有在派生类中被覆盖,它们只会在方法签名相同的情况下被覆盖。

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

Thsi 是调用 Derived 的 f 的正确代码

【讨论】:

  • 问题是关于 Java,而不是 C#。 Java 中不存在“虚拟”。
  • 感谢您的评论,我也修复了答案。
【解决方案3】:

方法的覆盖有三个条件,子类必须和父类同名、同参数、同返回值。但如果参数和返回值都不同,则覆盖不存在!即使两种方法是不同的方法!ok!像这样:

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 方法与 Parent.As 类中的 addV 方法不同!

【讨论】:

  • 只有方法的名称和参数列表必须完全相同。孩子的返回值可以是父母的返回值的子类。还有两个你省略的规则。 child 中的方法必须至少与 parent 中的方法一样可访问。并且子类不能抛出新的检查异常或更广泛的异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
  • 2022-01-21
相关资源
最近更新 更多