为什么java不允许父类的实例方法在子类中受到更多限制

发布于 2024-09-26 20:09:32 字数 232 浏览 2 评论 0原文

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

但是,它不允许使父类的实例方法在子类中受到更多限制。即它不允许使用与父类实例方法相同的名称,在子类中声明为私有。

如果子类没有重写实例方法,JVM 还会识别该实例方法的父类版本。

同样,如果子类使其更具限制性,那么为什么 JVM 不识别实例方法的父类版本呢?

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

Polymorphism allows the programmer either to inherit, override or to overload an instance method of Parent Class.

But, it won't allow to make an instance method of parent class as more restrictive in child class. i.e it wont allow to use same name of parent class instance method, to declare as private in the child class.

Also JVM identifies the parent class version of an instance method, if child class didn't override it.

Similarly why don't JVM identifies the parent class version of an instance method, if the child class makes it more restrictive?

The more restrictive method of parent class in child class can be considered as child class specific method instead of overridden method by compiler.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

许你一世情深 2024-10-03 20:09:32

这一切都是为了遵循里氏替换原则

为了使面向对象编程中的继承按预期运行,子类应该能够替换父类实例,并且不会破坏该类的用户。

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

This is all done in order to follow the Liskov Substitution Principle.

In order for inheritance in object oriented programming to behave as expected, a child class should be able to be substituted out for a parent class instance and not break a user of the class.

Making a child method more restrictive is basically saying "I don't want this method to be visible". Having the JVM automatically substitute out the parent class implementation in this case would just add a huge amount of confusion - just changing the call behavior might cause very unexpected behavior, even completely within the child class...

陌伤浅笑 2024-10-03 20:09:32

子类中父类的更严格的方法可以被视为子类特定方法

Java 作者可以实现这一点。还有许多其他事情,比如臭名昭著的多重继承。但这会使语言变得更加复杂,但好处却微乎其微。

如果您需要父方法的私有版本,为什么不给它起一个不同的名称呢?由于它只会从您的子班级中调用,因此不会有太大区别。

The more restrictive method of parent class in child class can be considered as child class specific method

Java authors could've implemented this. And many other things, like infamous multiple inheritance. But it would make language more complex for a very little benefit.

If you need a private version of parent's method, why don't you just give it different name? Since it'll be called from your child class only, there won't be much difference.

分分钟 2024-10-03 20:09:32

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 哲学。这或多或少就是使用当前解决方案的原因;即使无法使用特定功能,也会更简单。

Java creators decided that Java should be as simple as possible, your question could cause problems with codes like this :

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.
}

You provided a solution for this case, but it as has a flaw :

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 ?
}

There the solution is complicated and against the java philosophy. That's more or less why the current solution is used; more simple even if a specific feature can't be used.

旧话新听 2024-10-03 20:09:32

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

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
2

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

真正的问题是,为什么您希望它按照您所描述的方式运行?您是否有一个应用程序可以使用此功能?在我看来,这只会令人困惑。

If I understand you correctly, you're saying that I should be able to write:

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());
}

Then if I create an instance of type Foo2 and call bar from within the class, it should call Foo2.bar so I should get back 2, but if I call bar from outside the class, it should call Foo.bar so I get back 1.

That is, the output of the above program should be:
1
2

Well, as this is a question about the design of the language, I guess the simple answer is, "Because that's how the designers of Java decided to do it."

The real question is, Why would you want it to behave the way you describe? Do you have an application where this would be useful? It seems to me that it would just be confusing.

夜雨飘雪 2024-10-03 20:09:32

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

因此,您创建一个新类,其中包含您想要包装为成员的类,并通过设计自己的 API 来提供对您想要的内容的访问。当然,您不能使用新类来代替旧类,但这没有任何意义。如果这不是你想要做的,我 100% 同意 Reed Copsey 的回答(即使那是你想做的,我也 100% 同意)。

What you want to do is wrap the "parent" class into another using composition, not inheritance when you want to restrict access.

So you create a new class having the class you want to wrap as member and provide access to what you want by designing your own API. Of course, you cannot use the new class in place ot the old one, but that wouldn't make any sense. If that is not want you want to do, I agree 100% with Reed Copsey's answer (I agree 100% even if that is what you wanted to do).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文