与Java混淆覆盖访问级别

时间:2011-03-21 14:26:08

标签: java polymorphism

  

可能重复:
  Why can't you reduce the visibility of a method in a java subclass?

为什么我在子类中使用private覆盖超类中的public方法,但我无法将超类中的public方法覆盖为private方法在子类?

为什么呢?

提前谢谢。

5 个答案:

答案 0 :(得分:11)

覆盖方法无法降低可见性。允许这样做会违反Liskov Substitution Principle,它指出(简化)派生类B的所有对象必须具有与基类A相同的属性。在这种情况下,一个这样的“属性”将是一个公共方法foo,如果B具有相同的方法,那么它将“丢失”,但将其设为protected

此外,由于private方法未被继承(尝试从派生类调用它!),因此无法覆盖它们。您可以在基类中使用与public同名的private方法,但这不是覆盖,它只是一个具有相同名称的新方法,而不是其他关系。调用基类中的private方法将调用超类中的public方法,即使在超类的对象上执行也是如此!

换句话说:private方法从不使用运行时多态性。

请参阅此示例:

public static class Base {
    public void callBoth() {
        foo();
        bar();
    }

    private void foo() {
        System.out.println("Base.foo");
    }

    protected void bar() {
        System.out.println("Base.bar");
    }
}

public static class Sub extends Base {
    public void foo() {
        System.out.println("Sub.foo");
    }

    public void bar() {
        System.out.println("Sub.bar");
    }
}

执行new Sub().callBoth()时,输出将为:

Base.foo
Sub.bar

答案 1 :(得分:1)

因为它不会破坏类合约以使方法更具可用性。如果Kitten子类是Animal,而Animal有一个公共方法feed(),那么Kitten也必须有一个公共方法feed(),因为它必须可以像处理Animal的一个实例一样处理Kitten的任何实例。将访问级别重新定义为私有会破坏它。

答案 2 :(得分:1)

如果公共方法变为私有,那么就不可能将实例强制转换为其父类(因为其中一个方法不可用)。

如果私有方法变为公共方法,则可以将实例添加到其父类中(因为那时您将无法获取私有/公共覆盖方法)。

答案 3 :(得分:1)

访问级别不能比重写方法更多限制。

私有 - > [默认] - >受保护 - >公开

答案 4 :(得分:1)

通过覆盖你说你的子类可以用相同的api调用,但可能有不同的功能。公开内容会增加访问级别 - 因此您无法删除有保证的功能。

通过将公共方法设为私有(如果您实际上可以这样做),您将删除功能,从而破坏“合同”。它也没有意义,因为该方法仍然可以公开调用,只是公共调用将访问超类中的公共方法,这将是违反直觉的。