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

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

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

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

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

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

编辑:我应该提一下,这不是vanilla Java,实际上是Blackberry / J2ME。

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

对于您使用关键字的类…

  • private:仅对此类可见

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

  • protected:对此类,其包中的类以及此类的子类可见

  • 公众:任何class级都可以看到

顶级类不能被声明为私有 ,因为那时任何东西都无法访问它们。

但是你的问题源于他们为什么不被宣布保护 。 很明显,受保护的顶级类(它能够存在)本身是可见的(每个类本身都是可见的)。 很明显,受保护的顶级类对其包中的类是可见的。 但是,使其子类可见是很棘手的。 应该允许哪些类inheritance我们的受保护类?

如果是全部,那么我们的class级也可能是公开的 ,因为我们说任何class级都有权访问我们的受保护类。 如果它们都不是,那么我们的类也可能是包私有的 ,因为只有其他两个条件(对它自己和它的包中的东西可见)得到满足。 它不可能是“其中的一部分”,因为我们需要一种方法来定义哪些类可以访问它,这首先是可见性修饰符的用途。

因此,出于这些原因,顶级类不能私有的受保护的 ; 他们必须私人包装公共 包装

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

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

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

顶级类只允许使用 public和default 访问修饰符 。 但对于内部成员类,也允许使用其他修饰符。

这个摘要最有可能没有做到这一点。

您可以; 以下代码编译正常 :

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

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

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

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

您是否尝试过受保护的顶级课程(不允许)?

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

如果您只希望能够在同一个包中看到其他类的类,则默认(包 – 私有)修饰符将起作用,没有理由让受保护的修饰符起作用 – 它只会添加一个完全没有逻辑且无用的能力来查看来自其派生类的类,其中

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

b)可能发生,因为这个类及其派生类在同一个包中 – 无论如何,这将适用于默认(包 – 私有)修饰符。

顶级类不能具有protected范围,只有publicpackage 。 这是一个很好的参考,解释了类的范围修饰符的允许用途。