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

Posted

技术标签:

【中文标题】为啥你不能在 Java 中有一个受保护的抽象类?【英文标题】: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 实际上我认为我误解了受保护的可见性成员 【参考方案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,解释了在类上允许使用的作用域修饰符。

【讨论】:

以上是关于为啥你不能在 Java 中有一个受保护的抽象类?的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能将类定义为受保护的?

为啥我不能访问子类中的受保护变量?

java - 为啥在java中可以具有默认修饰符的类不能受到保护

为啥另一个包中的子类不能访问受保护的方法?

为啥我们不能在 Kotlin 的 Singleton 类(对象)中使用受保护的访问修饰符

抽象类的受保护与公共构造函数?有区别吗?