为什么java没有';不允许使父类的实例方法在子类中更具限制性

为什么java没有';不允许使父类的实例方法在子类中更具限制性,java,polymorphism,overriding,Java,Polymorphism,Overriding,多态性允许程序员继承、重写或重载父类的实例方法 但是,它不允许使父类的实例方法在子类中更具限制性。i、 它不允许使用父类实例方法的相同名称,在子类中声明为private 如果子类没有重写实例方法,JVM还会标识其父类版本 类似地,如果子类使实例方法更具限制性,为什么JVM不标识实例方法的父类版本 子类中父类的限制性更强的方法可以被视为子类特定的方法,而不是编译器重写的方法。这一切都是为了遵循 为了使面向对象编程中的继承行为符合预期,应该能够用子类替换父类实例,而不是破坏类的用户 使子方法更具限制

多态性允许程序员继承、重写或重载父类的实例方法

但是,它不允许使父类的实例方法在子类中更具限制性。i、 它不允许使用父类实例方法的相同名称,在子类中声明为private

如果子类没有重写实例方法,JVM还会标识其父类版本

类似地,如果子类使实例方法更具限制性,为什么JVM不标识实例方法的父类版本


子类中父类的限制性更强的方法可以被视为子类特定的方法,而不是编译器重写的方法。

这一切都是为了遵循

为了使面向对象编程中的继承行为符合预期,应该能够用子类替换父类实例,而不是破坏类的用户

使子方法更具限制性基本上是说“我不希望此方法可见”。在这种情况下,让JVM自动替换掉父类实现只会增加大量的混乱-仅仅更改调用行为可能会导致非常意外的行为,即使完全在子类中…

子类中父类的限制性更强的方法也可以被视为子类特定的方法

Java作者本可以实现这一点。还有很多其他事情,比如臭名昭著的多重继承。但这会让语言变得更复杂,只会带来一点点好处


如果您需要父方法的私有版本,为什么不给它不同的名称呢?由于它将仅从您的子类调用,因此不会有太大区别。

Java创建者认为Java应该尽可能简单,您的问题可能会导致类似以下代码的问题:

class A {
    public void methodA(){
    }
}
class B extends A {
    @Override
    private void methodA(){
    }
}
//
public static void main(String... args){
    A a = new B();
    a.methodA(); // Should call the overridden method but as it's private it can't work.
}
您为此案例提供了解决方案,但它有一个缺陷:

class A {
    public void methodA(){
    }

    public void methodB(){
        methodA();
    }
}
class B extends A {
    @Override
    protected void methodA(){
    }
}
//
public static void main(String... args){
    A a = new B();
    a.methodB(); // Will methodA from A be called or from B ?
}

在这里,解决方案是复杂的,并且与java哲学背道而驰。这或多或少就是为什么使用当前解决方案的原因;即使某个特定功能无法使用,也更简单。

如果我理解正确,你是说我应该能够写:

public class Foo
{
  public int bar()
  {
    return 1;
  }
}
public class Foo2 extends Foo
{
  private int bar()
  {
    return 2;
  }
  public int barBar()
  {
    return bar();
  }
}
public static void main(String[] args())
{
  Foo2 foo2=new Foo2();
  System.out.println(foo2.bar());
  System.out.println(foo2.barBar());
}
然后,如果我在类内创建Foo2类型的实例并调用bar,它应该调用Foo2.bar,这样我就可以返回2,但是如果我在类外调用bar,它应该调用Foo.bar,这样我就可以返回1

即,上述程序的输出应为: 1. 二,

好的,因为这是一个关于语言设计的问题,我想简单的答案是,“因为Java的设计者就是这样决定的。”


真正的问题是,你为什么希望它按照你描述的方式运行?您是否有这样的应用程序?在我看来,这会让人感到困惑。

当您想要限制访问时,您要做的是使用组合将“父”类包装到另一个类中,而不是继承


因此,您创建了一个新类,该类包含您希望包装为成员的类,并通过设计自己的API提供对所需内容的访问。当然,不能使用新类代替旧类,但这没有任何意义。如果你不想这样做,我100%同意里德·科佩的回答(即使你想这样做,我也100%同意)

这个答案需要一些解释。但是是的,归根结底就是这个+1编辑:谢谢:)不是为了我,是为了别人。我非常了解利斯科夫原理;)@德尔南:呵呵。。。这样看起来更好吗?你的回答作为对@Colin Hebert答案的评论将使他的答案完整。