当前位置: 首页 > 知识库问答 >
问题:

为什么Java允许增加子类中受保护方法的可见性?

燕英逸
2023-03-14
abstract class Base{
      protected abstract void a();
}

class Child extends Base{
      @Override
      public void a(){
          //why is this valid
      }
}

为什么我们不能降低能见度,但可以提高能见度?

此外,我需要实现模板模式,其中可见的公共方法只能是基类。

abstract class Base{
      public void callA(){
      //do some important stuff
      a();
      }

      protected abstract void a();
}

class Child extends Base{
      @Override
      public void a(){
          //why is this valid
      }
}

共有1个答案

常温文
2023-03-14

为什么不允许降低可见性已经在其他响应中解释了(这会破坏父类的契约)。

但是为什么允许它增加一个方法的可见性呢?首先,它不会违反任何合同,所以没有理由不允许。有时,当在子类中不保护方法是有意义的时候,这可能很方便。

其次,不允许它可能会产生副作用,有时会使扩展类和实现接口变得不可能:

interface Interface1 {
   public void method();
}

public class Parent {
   protected abstract void method();
}

public class Child extends Parent implements Interface1 {
   @Override
   public void method() {
   }
   //This would be impossible if the visibility of method() in class Parent could not be increased.
}

关于你的第二个问题,你对此无能为力。您必须相信实现子类的人不会做任何破坏您实现的事情。即使java不允许增加可见性,这仍然不能解决问题,因为可以创建一个具有不同名称的公共方法来调用抽象方法:

class Child extends Base{
      @Override
      protected void a(){

      }

      public void a2() {
           a(); //This would have the same problems that allowing to increase the visibility.
      }
}
 类似资料:
  • 问题内容: 为什么在最终课程中允许受保护的成员? 这不应该是编译时错误吗? 编辑:正如人们指出的那样,您可以使用默认修饰符来获得相同的程序包访问权限。它的行为应该完全相同,因为protected是默认+子类,而final修饰符明确地拒绝了子类,因此我认为答案不只是提供相同的程序包访问。 问题答案: 该改性剂是必要的方法其覆盖从基类的方法,在没有那些构件暴露于所述。 通常,您可以引入很多不必要的规则

  • 问题内容: 看起来很傻,但是我真的很困惑。请看下面的代码: 我已经从Oracle文档读取和在这里为好,即 protected成员在另一个包也子类可见 。因此fun()应该在第二包的子类中可见。那为什么会出错呢? 我是否非常想念一些非常明显的东西? 问题答案: 在Java语言规范说 可以从包的外部访问对象的受保护成员或构造函数,而在包中只能通过负责该对象实现的代码声明该对象。 这意味着,如果要在原始

  • 问题内容: 关键字授予对相同包和子类(http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html)中的类的访问权限。 现在,每个类都有一个超类(http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html)。 因此,我得出结论,即使每个类都可以访问的方法。

  • 问题内容: 有谁知道, 为什么 AbstractList (以及ArrayList)中的removeRange方法是?它看起来像是一个定义明确且有用的操作,但是仍然要使用它,我们不得不对List实现进行子类化。 有一些隐藏的理由吗?对我来说似乎莫名其妙。 问题答案: 是的,因为这不是您从外部代码中删除范围的方式。相反,请执行以下操作: 这实际上是在幕后。† OP询问为什么不属于公共API。原因在《

  • 问题内容: 出于好奇, 为什么将方法的访问修饰符设置为。为什么不能呢?有人可以向我解释这背后的任何具体原因吗? 另外,我知道该方法仅被调用一次。如果我在程序内部两次调用它,会发生什么情况?垃圾收集器会再次调用吗? 问题答案: 我用另一个问题回答您的问题: 为什么方法不应该受到保护? 通常,您应该尝试使事物尽可能私密。这就是封装的全部意义所在。否则,您 什么都 可以做。不能(因为派生类应该能够访问它

  • 问题内容: 考虑从官方的这段代码OpenJDK源码的: 这里的用例是什么,为什么一般来说编写这样的代码有意义? 问题答案: 仍然可以通过同一包中的代码访问成员。我的猜测是,该类在某些早期版本(可能甚至不是公共版本)中曾经是非最终的,然后被设置为最终的,并且受保护的方法保持原样,因为在使用它的同一包中可能有代码(而不是之所以将其更改为私有包,仅仅是因为没有人看到这样做的好处。