用Java重写私有方法

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (29)

正如这里简洁地描述的那样,在Java中重写私有方法是无效的,因为父类的私有方法是“自动最终的,并且不能从派生类中隐藏”。我的问题主要是学术问题。

如果不允许父类的私有方法被“重载”(即,在一个子类中,独立执行,具有相同的签名),那么它是不是违反了封装?根据封装原则,父类的私有方法不能被子类访问或继承。它是隐藏的。

那么,为什么要限制儿童班级使用相同的名称/签名来执行自己的方法呢?这是否有一个良好的理论基础,还是仅仅是某种实用的解决方案?其他语言(C ++或C#)对此有不同的规则吗?

提问于
用户回答回答于

那么,允许私有方法被覆盖将导致封装泄漏或安全风险。如果我们认为这是可能的,那么我们会得到以下情况:

  1. 假设有一个私有方法,boolean hasCredentials()那么扩展类可以像这样简单地覆盖它: boolean hasCredentials() { return true; } 从而打破安全检查。
  2. 原始类防止这种情况的唯一方法是声明其方法final。但是现在,这是通过封装来泄漏实现信息的,因为派生类现在不能再创建一个方法hasCredentials- 它会与基类中定义的方法冲突。 这很糟糕:可以说这种方法一开始并不存在Base。现在,一个实现者可以合法地派生一个类Derived并给它一个hasCredentials按预期工作的方法。 但是现在,原始类的版本Base发布了。它的公共接口不会改变(也不会改变它的不变量),所以我们必须期望它不会破坏现有的代码。只有它,因为现在有一个名称与派生类中的方法冲突。

我认为这个问题源于一个误解:

它是如何/不是/违反了封装,不允许父代的私有方法被“重写”(即,在一个子类中独立执行,具有相同的签名)

括号内的文字与之前的文字相反。Java 确实允许你“在一个子类中独立地实现[私有方法],具有相同的签名”。不允许这将违反封装,正如我上面解释的。

但是“不允许父母的私人方法被”重写“”是不同的,并且是确保封装的必要条件。

用户回答回答于

您无法重写私有方法,但可以在派生类中引入一个没有问题的方法。这编译罚款:

class Base
{
   private void foo()
   {
   }
}

class Child extends Base
{
    private void foo()
    {
    }
}

请注意,如果您尝试将@Override注释应用于Child.foo()您,将会收到编译时错误。只要你将你的编译器/ IDE设置为给你警告或错误,如果你缺少一个@Override注释,一切都会好的。无可否认,我更喜欢C#override作为关键字的方式,但在Java中这样做显然已经太晚了。

至于C#处理“覆盖”一个私有方法 - 私有方法首先不能是虚拟的,但是你当然可以在基类中引入一个与私有方法同名的新私有方法。

扫码关注云+社区