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

14

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

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

但是当我试图将AbstractFoo设为protected时,编译时会报错,提示这是一个非法的修饰符。

protected abstract class AbstractFoo implements Bar {
  //Code goes here
}
为什么在Java中不能有一个受保护的抽象类?
编辑:我应该提到这不是普通的Java,而是Blackberry / J2ME。

2
这是一个顶层类还是内部类? - Nate W.
2
请注意,abstract 与此无关。 - Paul Bellora
你为什么想要做这样的事情? - parapura rajkumar
@Shakedown 这是一个顶级类。 - binarycreations
因为我想要封装,而protected提供了这种功能。 - binarycreations
1
@parapurarajkumar,实际上我认为我误解了受保护的可见性成员。 - binarycreations
6个回答

33
正如其他人指出的那样,这里的限制与你的类是抽象的无关,而与你选择使用的可见性修饰符有关。请记住每个可见性修饰符的含义:
对于你正在使用关键字的类...
- private:仅对该类可见 - (默认/包私有):仅对该类及其包中的类可见 - protected:对该类、该类所在的包中的类以及此类的子类可见 - public:对任何类可见
顶层类不能声明为private,因为没有任何东西能够访问它们。
但你的问题围绕为什么不能将它们声明为protected。很明显,受保护的顶级类(如果能存在)将对自身可见(每个类对自身都可见)。同样清晰的是,受保护的顶级类将对其包中的类可见。然而,使它对其子类可见就比较棘手。哪些类应被允许继承我们的受保护类?
如果是所有类,那么我们的类可能与public相当,因为我们正在说任何类都有权访问我们的受保护类。如果没有一个,则我们的类可能相当于package-private,因为只满足了其他两个条件(对自身和其包中的内容可见)。它也不能是“其中的一些”,因为我们需要一种定义哪些类可以访问它的方式,而这正是可见性修饰符的作用。
因此,出于这些原因,顶级类不能是private或protected;它们必须是package-private或public。

6

顶层类只能是public或者包级私有(默认)。

public class PublicClass { 

    protected class InnerClass { } //protected makes sense here

}

class PackagePrivateClass { }

由于PublicClassPackagePrivateClass都是顶级类,因此它们不能具有其他访问修饰符,如privateprotected

只有公共和默认的访问修饰符允许用于顶级类。 但对于内部成员类,还允许使用其他修饰符。

这里很可能与抽象无关。


protected 实际上意味着在派生类和包中可见,因此这不是问题所在。 - asenovm
也许可以解释一下为什么这里要用-1,但我不理解。 - Paul Bellora
@iLate:所以,你的意思是可以有一个受保护的顶级类,但不能有一个受保护的内部类? - Bhesh Gurung
@Bhesh Gurung 绝不是这样。我只是说受保护的修饰符包括包私有可见性。请参阅我的帖子了解详细信息。 - asenovm

4
你可以编译以下代码,代码可正常编译:
public class Main {

    interface Bar {}

    protected abstract class AbstractFoo implements Bar {}

    public static void main(String[] args) {}
}

0

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

如果您只想从同一包中的其他类中看到该类,则默认(包私有)修饰符将起作用,没有理由使用protected修饰符-它只会增加一个完全不合逻辑和无用的功能,即从其派生类中查看该类,

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

b)如果此类及其派生类在同一包中,则可以发生-这将与默认(包私有)修饰符一起使用。


0

顶层类不能使用protected作用域,只能使用publicpackage。这里有一个很好的参考资料,解释了类作用域修饰符的可允许使用情况。


0

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

class prot
{
    public abstract class pubab
    {
    }

    protected abstract class protab
    {
    }

    abstract class packprivab
    {
    }

    private abstract class privab
    {
    }
}

这让我想到在Java中可以有一个受保护的抽象类。事实上,你也可以有一个私有的抽象类。

你曾试图创建一个受保护的顶级类吗?(不允许)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接