【问题标题】:private method of superclass executes on subclass reference超类的私有方法在子类引用上执行
【发布时间】:2014-12-28 16:02:36
【问题描述】:

给定以下代码:

超类:

package poc.poc;

public class SuperClass {

    private void method() {
    System.out.println("SuperClass!");
    }

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    SuperClass s = new SubClass();
    s.method();
    }

}

子类:

package poc.poc;

public class SubClass extends SuperClass {
    public void method() {
    System.out.println("Subclass!");
    }
}

当我运行 SuperClass 的 main 方法时,我希望得到某种异常,但实际上运行的是 SuperClass 中的代码,而不是 SubClass 中的代码,因此正在运行子类实例上的超类类型的实例方法。

为什么会这样? 编辑:这不违反封装吗?

附:当更改为受保护而不是私有修饰符时,多态性开始发挥作用,我们又回到了我称之为“预期行为”的东西

【问题讨论】:

  • 这是因为私有方法在范围内,因为您在同一个文件中。如果您在第三个文件中创建 main,您的代码将无法编译。
  • 在SubClass'method上打个@Override注解就明白了。

标签: java oop inheritance static


【解决方案1】:

没有办法覆盖私有方法。相反,子类隐藏它。这意味着当以多态方式使用子类时,该方法不被视为父类的现有方法之一。这就像一个全新的方法,不能通过多态获得。

私有方法不是父类契约的一部分。多态性仅适用于作为父合约一部分的方法。如果不是这样,您可以通过更改作者希望它是私有的实现来使类的行为与其合同不同。如果作者希望您这样做,他们会改用protected。实际上,private 方法类似于 final

在这个特定的主方法中,因为它是在实际父类中定义的,所以它能够看到一个私有方法,因此能够调用它。如果您的 main 方法已经在任何其他类中并试图调用它,它就会失败。

【讨论】:

    【解决方案2】:

    私有方法不能被覆盖,仅此而已解释了您在此处看到的内容。您可以在 main 中调用该方法,因为 main 在同一个类中,否则将不可能。

    您正确分析了将 private 更改为 protected 时会发生什么:该方法现在是可重写的,并且在子类实例上调用它时会执行它的“最近”定义。

    【讨论】:

    • 子类怎么可能真正运行超类私有部分的代码,这不违反封装原则吗?
    • 如果私有方法会调用可覆盖的方法怎么办?那会发生什么?
    • 不会发生这种情况,因为您只能从同一类的 main 方法中执行此操作。您无法从其他任何地方执行此操作,因此不存在封装问题
    • @VladIlie 不会有什么不同,如果你愿意,我可以给你举个例子说明它是如何有用的
    • 但是是调用 SuperClass 方法,还是调用 SubClass 方法?
    猜你喜欢
    • 2012-03-03
    • 2018-08-22
    • 2012-08-12
    • 1970-01-01
    • 2015-04-23
    • 2017-07-15
    • 2011-02-19
    • 2020-09-17
    相关资源
    最近更新 更多