Java 为什么一个类不能被定义为受保护的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3869556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can a class not be defined as protected?
提问by M.J.
I know this is a stupid question, but I still have a doubt which needs to be cleared.
我知道这是一个愚蠢的问题,但我仍然有一个疑问需要清除。
My question is, why can we not define a class as protected
?
我的问题是,为什么我们不能将类定义为protected
?
I know that we can't, but why? There should be some specific reason.
我知道我们不能,但为什么呢?应该有一些具体的原因。
采纳答案by Nikita Rybak
Because it makes no sense.
因为没有意义。
Protected class member (method or variable) is just like package-private (default visibility), except that it also can be accessed from subclasses.
Since there's no such concept as 'subpackage' or 'package-inheritance' in Java, declaring class protected or package-private would be the same thing.
受保护的类成员(方法或变量)就像包私有(默认可见性)一样,除了它也可以从子类访问。
由于在 Java 中没有“子包”或“包继承”这样的概念,因此声明类受保护或包私有将是同一件事。
You can declare nested and inner classes as protected or private, though.
不过,您可以将嵌套类和内部类声明为受保护的或私有的。
回答by irreputable
public class A
{
protected class B
{
}
}
回答by Akash5288
As you know default is for package level access and protected is for package level plus non-package classes but which extends this class (Point to be noted here is you can extend the class only if it is visible!). Let's put it in this way:
如您所知,默认用于包级别访问,而受保护用于包级别和非包类,但它扩展了这个类(这里要注意的是,您只能在类可见时扩展该类!)。让我们这样说:
- protected top-level class would be visible to classes in its package.
- now making it visible outside the package (subclasses) is bit confusing and tricky. Which classes should be allowed to inherit our protected class?
- If all the classes are allowed to subclass then it will be similar to public access specifier.
- If none then it is similar to default.
- 受保护的顶级类对其包中的类可见。
- 现在让它在包(子类)之外可见有点令人困惑和棘手。应该允许哪些类继承我们的受保护类?
- 如果所有类都被允许子类化,那么它将类似于公共访问说明符。
- 如果没有,则它类似于默认值。
Since there is no way to restrict this class being subclassed by only few classes (we cannot restrict class being inherited by only few classes out of all the available classes in a package/outside of a package), there is no use of protected access specifiers for top level classes. Hence it is not allowed.
由于没有办法限制这个类只被少数类继承(我们不能限制类只被包中/包外所有可用类中的少数类继承),因此没有使用受保护的访问说明符对于顶级课程。因此是不允许的。
回答by madhu
behavior of “protected” = behavior of “default”+ “use it in any subclass in any package”.
“protected”的行为=“default”的行为+“在任何包的任何子类中使用它”。
Anyway we have default access modifier for class, only advantage we can get from protected access modifier is:- by using it in any package through subclassing. But for subclass, visibility of parent “protected”class would be private. So it can't be accessed. Basically if you have a protected top-level class, no outer class can gain access by subclassing it. So protected for a top-level class is meaningless.
无论如何,我们有类的默认访问修饰符,我们可以从受保护的访问修饰符中获得的唯一优势是:- 通过子类化在任何包中使用它。但是对于子类,父“受保护”类的可见性将是私有的。所以无法访问。基本上,如果您有一个受保护的顶级类,则没有外部类可以通过子类化它来获得访问权限。所以保护一个顶级类是没有意义的。
回答by Shruthi reddy
Protected is not similar to public. Protected has both package level access plus can be accessed outside of packages only by inheritance..If a class say A outside a package INHERITS a class from other package(with protected method by using INHERITANCE) it can access the methods of this class B which has protected methods but the sub-classes derived from this class i.e., A can't access the protected methods..the opposite happens with public..
Protected 与 public 不同。Protected 具有包级别的访问权限,并且只能通过继承在包外访问。 如果一个类说包外的 A 从其他包继承了一个类(通过使用 INHERITANCE 使用受保护的方法),它可以访问这个类 B 的方法有受保护的方法,但从这个类派生的子类,即 A 不能访问受保护的方法..相反的情况发生在公共..
Example:
例子:
package 2;
class B
{
protected void method1()
{
}
}
package 1;
import 2.B;
class A extends B
{
//can access protected method
}
class C extends A
{
//can't access the protected method
}
回答by Fruit
@Nikita Rybak answerhas good points but lack of details, i can't simply get the idea without think deeply myself, the following is what i thought and now i should completely understood the reason.
@Nikita Rybak 的回答有好点,但缺乏细节,我不能在没有深入思考的情况下简单地得到这个想法,以下是我的想法,现在我应该完全理解原因了。
Four access modifiers, assume the 1st level is public and 4th level is private (based on this tablein sequence). The first thing we should know is why class cannot defined as private in top-level.
四个访问修饰符,假设第 1 级是公共的,第 4 级是私有的(按顺序基于此表)。我们应该知道的第一件事是为什么类不能在顶级定义为私有。
So if "private class foo"(A private member defined, i.e. class itself is a member) allow, what is the outer (which contains the member) ? File scope ?No, file outer is pointless because even multiple classes in single file will be compile into separate class files. So the outer is package. But the 3rd level default access modifier already means "package-private". So the 4th level private access modifier will not be used/allowed.
因此,如果“私有类 foo”(定义的私有成员,即类本身是成员)允许,那么外部(包含该成员)是什么?文件范围 ? 不,文件外部是没有意义的,因为即使单个文件中的多个类也会被编译成单独的类文件。所以外面是 package。但是第三级默认访问修饰符已经意味着“package-private”。因此将不会使用/允许第 4 级私有访问修饰符。
But nested private classis allow because the direct outer is class, not package, e.g.:
但是允许嵌套私有类,因为直接外部是类,而不是包,例如:
class PrivateNestedMain {
private static class Inner {
public static void main(String[] args) {
System.out.println("Hello from Inner!");
}
}
}
Now what if "protected class foo" allow ? protected main characteristicis subclass, so the outer(package) SHOULD(due to up-to scope, but still it's optional) provide style of subclass, i.e. sub-package, or package A extends package B
, but we know no such thing. So protected can't use full potential(main scope is subclass-wide) in top-level which the outer is package(i.e. no such sub-package thing), but protected can use full potential in nested class which the outer is class(i.e. can be subclass):
现在如果“受保护的类 foo”允许呢?受保护的主要特征是子类,所以外层(包)应该(由于作用域最大,但仍然是可选的)提供子类的样式,即子包或package A extends package B
,但我们不知道这样的事情。所以受保护不能在外部是包的顶级(即没有这样的子包的东西)中使用全部潜力(主范围是子类范围的),但是受保护可以在外部是类的嵌套类中使用全部潜力(即可以是子类):
class ProtectedNestedMain {
protected static class Inner {
public static void main(String[] args) {
System.out.println("Hello from Inner!");
}
}
}
Note that the above said "can't use full potential" due to it can't reach subclass-wide merely because no outer subclass, that's means actually protected can be allow, it's just a matter of choice to avoid duplicate the job of package-private if outer not subclass-able, see below.
请注意,上面说的“不能充分利用潜力”,因为它不能仅仅因为没有外部子类而无法到达子类范围内,这意味着实际上可以允许受保护,这只是一个选择问题,以避免重复包的工作-private 如果外部不能子类化,请参见下文。
My confusing is mainly caused by the famous table at https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html:
我的困惑主要是由https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html 上的著名表格引起的:
If 1st level(public) and 3rd level (package-private) allowed, how on earth the in-between 2nd level (protected) not allowed ?
如果允许第一级(公共)和第三级(包私有),那么中间的第二级(受保护)怎么不允许?
public support subclass so easy to misleading. The correct way to read this table is
公共支持子类所以容易误导。阅读此表的正确方法是
public support subclass if the outer has subclass feature.
如果外部具有子类功能,则公共支持子类。
The same misleading apply to package-private, package-private doesn't support subclass (Nin cell) doesn't means subclass concept apply in outer.
同样的误导适用于包私有,包私有不支持子类(单元格中的N)并不意味着子类概念适用于外部。
That's means we should ignore the Subclasscolumn if subclass feature is not available in outer:
这意味着如果子类功能在外部不可用,我们应该忽略子类列:
As we can see now, both protected and package-private are the same level now (Y-Y-N), no more confusion about why in-between level is not allowed. Overall, Java pick only package-private over protected to avoid confusing(it's just a matter of choice, but protected main characteristicis subclass, so package-private is superior), and the result, only 2 access modifiers allowed in top-level:
正如我们现在看到的,protected 和 package-private 现在是同一级别(YYN),不再混淆为什么不允许中间级别。总的来说,Java 只选择 package-private 而不是 protected 以避免混淆(这只是一个选择问题,但是 protected 的主要特征是子类,所以 package-private 是优越的),结果,顶级只允许 2 个访问修饰符:
At the top level—public, or package-private (no explicit modifier).
在顶层 — 公共或包私有(无显式修饰符)。
回答by Naresh Joshi
Defining a field protected makes that field accessible inside the package as well as outside the package through inheritance only (Only inside the child class).
定义一个字段 protected 使得该字段在包内部和包外部都可以通过继承访问(仅在子类内部)。
So If we are allowed to make a class protected then we can access it inside the package very easily but for accessing that class outside of the package we first need to extend that entity in which this class is defined which is its package.
因此,如果我们允许保护类,那么我们可以很容易地在包内访问它,但是为了在包外访问该类,我们首先需要扩展定义该类的实体,即它的包。
And since a package can not be extended (can be imported), defining a class protected will again make it package-private which is similar to defining it as default which we can already do. Therefore there is no benefit of defining a class private it will only make things ambiguous.
并且由于包无法扩展(可以导入),定义一个受保护的类将再次使其成为包私有的,这类似于我们已经可以将其定义为默认值。因此,定义一个私有类没有任何好处,它只会使事情变得模棱两可。
For more information read Why an outer Java class can't be private or protected
有关更多信息,请阅读为什么外部 Java 类不能是私有的或受保护的
回答by Narendra Singh
Protected: VISIBLE only to package level*.
受保护:仅对包级别可见*。
class is defined protected---> it cannot be extendedfrom outside package(not visible).
类被定义为受保护---> 它不能从外部包(不可见)扩展。
And if it cannot be extended then it is meaningless to keep it as protected, because then it will become defaultaccess which is allowed.
如果它不能扩展,那么将它保持为protected是没有意义的,因为那样它将成为允许的默认访问。
Same applies to privatedefined classes.
这同样适用于私有定义的类。
Note :Nested or inner classes can be defined protectedor private.
注意:嵌套类或内部类可以定义为protected或private。
*: Explore protectedkeyword, for this answer I made it succinct.
*:探索受保护的关键字,对于这个答案,我使它简洁。
回答by k-s
The answer from @Akash5288 made no sense to me:
@Akash5288 的回答对我来说毫无意义:
If all the classes are allowed to subclass then it will be similar to public access specifier.
Since there is no way to restrict this class being subclassed by only few classes (we cannot restrict class being inherited by only few classes out of all the available classes in a package/outside of a package), there is no use of protected access specifiers for top level classes. Hence it is not allowed.
如果所有类都被允许子类化,那么它将类似于公共访问说明符。
由于没有办法限制这个类只被少数类继承(我们不能限制类只被包中/包外所有可用类中的少数类继承),因此没有使用受保护的访问说明符对于顶级课程。因此是不允许的。
You can then apply the same logic to protected methods and variables, they are also then "similar to public". All classes outside of a package can extend our public class and use its protected methods. Why is restricting methods and variables to extended classes ok, but restricting the whole class not ok? "Similar to public" is not "same as public". My interpretation is that it is perfectly fine to allow a protected class, as it is fine to allow protected methods.
然后您可以将相同的逻辑应用于受保护的方法和变量,它们也“类似于公共”。包外的所有类都可以扩展我们的公共类并使用其受保护的方法。为什么将方法和变量限制到扩展类可以,但限制整个类不行?“与公共相似”并不“与公共相同”。我的解释是,允许受保护的类是完全可以的,因为允许受保护的方法是可以的。
The answer "you can not extend a class you can not access/see" is more logical.
“您无法扩展您无法访问/查看的类”的答案更合乎逻辑。
回答by Anurag Prasad
What makes sense to this question is that, JVM is written in C (Sun JVM) and C++(oracle JVM) so during compilation, we are going to create .class files out of our java file and if we declare a class with Protected keyword then it will not be accessed by JVM.
这个问题的意义在于,JVM 是用 C(Sun JVM)和 C++(oracle JVM)编写的,因此在编译期间,我们将从我们的 java 文件中创建 .class 文件,如果我们使用 Protected 关键字声明一个类那么它不会被JVM访问。
The answer why protected class will not be accessed by JVM is that, since protected fields are accessible within same package or to diffrent package through inheritance only and JVM is not written in a way so that it will inherit will class. Hope this satisfies this question :)
JVM 不会访问受保护类的答案是,由于受保护的字段可以在同一包内访问或仅通过继承访问不同的包,并且 JVM 的编写方式不会使其继承将类。希望这能满足这个问题:)
Similarly, A top level class can't be private. Explanation as below:
同样,顶级类不能是私有的。解释如下:
So what will happen if we will define a class private, that class will only be accessible within the entity in which it is defined which in our case is its package?
那么如果我们定义一个私有类会发生什么,该类只能在定义它的实体中访问,在我们的例子中是它的包?
So defining private access to the class will make it accessible inside the same package which default keyword already do for us, Therefore there is no benefit of defining a class private it will only make things ambiguous.
因此,定义对类的私有访问将使其在默认关键字已经为我们所做的同一个包中可访问,因此定义类私有没有任何好处,它只会使事情变得模棱两可。