【问题标题】:Why can't you have a protected abstract class in Java?为什么你不能在 Java 中有一个受保护的抽象类?
【发布时间】:2011-12-30 21:28:25
【问题描述】:

我有一个抽象类,看起来像:

abstract class AbstractFoo implements Bar {
  //Code goes here
}

但是,当我尝试使 AbstractFoo 受保护时,我收到一个错误编译时错误,抱怨它是一个非法修饰符。

protected abstract class AbstractFoo implements Bar {
  //Code goes here
}

为什么在 Java 中不能有一个受保护的抽象类?

编辑:我可能应该提一下,这不是普通的 Java,实际上是 Blackberry / J2ME。

【问题讨论】:

  • 这是顶级类还是内部类?
  • 请注意abstract与此无关。
  • 你为什么要做这样的事情?
  • @Shakedown 这是一个顶级课程
  • @parapurarajkumar 实际上我认为我误解了受保护的可见性成员

标签: java blackberry java-me abstract protected


【解决方案1】:

正如许多其他人所指出的,这里的限制与您的类是抽象的这一事实无关,而是与您选择使用的可见性修饰符有关。请记住每个可见性修饰符的含义:

对于您使用关键字的类...

  • private:仅对此类可见

  • (默认/包私有):仅对此类及其包中的类可见

  • 受保护:对此类、其包中的类以及此类的子类可见

  • public:对任何类可见

顶级类不能声明为private,因为这样就没有任何东西可以访问它们了。

但您的问题源于为什么它们可能不被宣布为受保护。很明显,一个受保护的顶级类(如果它能够存在的话)对它自己是可见的(每个类对它自己都是可见的)。同样清楚的是,受保护的顶级类对其包中的类是可见的。然而,让它对其子类可见是很棘手的。应该允许哪些类继承我们的受保护类?

如果是所有这些,那么我们的类还不如public,因为这样我们就说任何类都有权访问我们的受保护类。如果它们都不是,那么我们的类也可能是 package-private,因为只满足其他两个条件(对自身可见以及在其包中的东西)。而且它不能是“其中一些”,因为我们需要一种方法来定义哪些类可以访问它,这就是可见性修饰符最初的用途。

因此,由于这些原因,顶级类不能私有受保护;它们必须package-privatepublic

【讨论】:

    【解决方案2】:

    顶级类只能是公共的或包私有的(默认)。

    public class PublicClass { 
    
        protected class InnerClass { } //protected makes sense here
    
    }
    
    class PackagePrivateClass { }
    

    因为:PublicClassPackagePrivateClass 都是顶级类,它们不能有其他访问修饰符 privateprotected

    只有公共和默认的 access-modifiers 被允许用于顶级类。 但对于内部成员类,其他修饰符也是允许的。

    那个摘要很可能在这里没有任何作用。

    【讨论】:

    • protected 实际上意味着在派生类中可见 + 在包中,所以这不是这里的问题。
    • 也许可以解释一下原因,但我不明白这里的-1。
    • @iLate:所以,你的意思是可以有一个受保护的顶级类而不能有一个受保护的内部类?
    • @Bhesh Gurung 绝不是。我只说受保护的修饰符包括包私有可见性。详情见我的帖子。
    【解决方案3】:

    你可以;以下代码compiles fine:

    public class Main {
    
        interface Bar {}
    
        protected abstract class AbstractFoo implements Bar {}
    
        public static void main(String[] args) {}
    }
    

    【讨论】:

      【解决方案4】:

      我不相信问题的前提。我成功编译了以下代码:

      class prot
      {
          public abstract class pubab
          {
          }
      
          protected abstract class protab
          {
          }
      
          abstract class packprivab
          {
          }
      
          private abstract class privab
          {
          }
      }
      

      这表明你可以在 java 中拥有一个受保护的抽象类。就此而言,您可以拥有一个私有抽象类。

      您是否尝试拥有一个受保护的顶级类(不允许)?

      【讨论】:

        【解决方案5】:

        IMO,它看起来确实是一个非法修饰符,因为受保护意味着它应该在包中可见 + 在派生类中。但是为了声明某个类扩展了这个受保护的类,您首先需要能够从那里看到它,这是不可能的,因为它只能从派生类中看到(假设超类和子类不在同一个包)。

        如果您只想能够从同一包中的其他类中查看该类,则 default(package-private) 修饰符将起作用,protected 修饰符没有理由起作用 - 它只会增加一个完全不合逻辑且无用的能力从其派生类中查看该类,

        a) 如果此类及其派生类不在同一个包中,则不会发生。

        b) 可能会发生,因为此类及其派生类在同一个包中 - 无论如何,这将与默认 (package-private) 修饰符一起使用。

        【讨论】:

          【解决方案6】:

          顶级类不能有protected 范围,只能有publicpackage。这是一个nice reference,解释了在类上允许使用的作用域修饰符。

          【讨论】:

            猜你喜欢
            • 2019-11-18
            • 1970-01-01
            • 1970-01-01
            • 2011-04-21
            • 2014-03-08
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多