为什么类不能被定义为受保护的?

发布于 2024-09-26 18:04:30 字数 75 浏览 1 评论 0原文

为什么我们不能将类定义为protected

我知道我们不能,但为什么呢?应该有一些具体的原因。

Why can we not define a class as protected?

I know that we can't, but why? There should be some specific reason.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

当梦初醒 2024-10-03 18:04:30

因为这没有意义。

受保护的类成员(方法或变量)就像包私有(默认可见性)一样,只不过它也可以从子类访问。
由于 Java 中没有“子包”或“包继承”这样的概念,因此声明类 protected 或 package-private 是一样的。

不过,您可以将嵌套类和内部类声明为受保护的或私有的。

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.

You can declare nested and inner classes as protected or private, though.

我为君王 2024-10-03 18:04:30

如您所知,默认值用于包级别访问,受保护用于包级别加上非包类,但它扩展了此类(这里要注意的一点是,只有在该类可见时才可以扩展该类!)。
让我们这样说:

  • 受保护的顶级类对其包中的类是可见的。
  • 现在使其在包(子类)外部可见有点令人困惑和棘手。哪些类应该被允许继承我们的受保护类?
  • 如果所有类都允许子类化,那么它将类似于公共访问说明符。
  • 如果没有,则与默认类似。

由于无法限制此类仅由少数类子类化(我们无法限制类仅由包内/包外的所有可用类中的少数类继承),因此不使用受保护的访问说明符为顶级课程。因此这是不允许的。

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.

贱贱哒 2024-10-03 18:04:30
public class A
{
    protected class B
    {
    }
}
public class A
{
    protected class B
    {
    }
}
鹤舞 2024-10-03 18:04:30

定义受保护的字段使得该字段只能通过继承在包内部和包外部访问(仅在子类内部)。

因此,如果我们允许对一个类进行保护,那么我们可以很容易地在包内访问它,但是为了在包外访问该类,我们首先需要扩展定义该类的实体,即它的包。

由于包不能扩展(可以导入),定义一个受保护的类将再次使其成为包私有,这类似于我们已经可以将其定义为默认值。
因此,将类定义为私有没有任何好处,它只会使事情变得模糊。

有关更多信息,请阅读 为什么外部 Java 类不能是私有的或受保护的

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).

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

我偏爱纯白色 2024-10-03 18:04:30

@Nikita Rybak 的回答有很好的观点,但缺乏细节,我无法在不深入思考的情况下简单地理解这个想法,以下是我的想法,现在我应该完全理解原因了。

四个访问修饰符,假设第一级是公共的,第四级是私有的(基于此 按顺序)。首先我们应该知道的是为什么类不能在顶层定义为私有的。

因此,如果“private class foo”(定义的私有成员,即类本身是成员)允许,那么外部(包含该成员)是什么? 文件范围?不,文件外部是没有意义的,因为即使单个文件中的多个类也会被编译成单独的类文件。 所以外部是包装。但是第三级默认访问修饰符已经意味着“package-private”。因此,将不会使用/允许第四级私有访问修饰符。

但是嵌套私有类是允许的,因为直接外部是类,而不是包,eg

class PrivateNestedMain {
    private static class Inner {
        public static void main(String[] args) {
            System.out.println("Hello from Inner!");
        }
    }
}

现在如果“受保护的类 foo”允许怎么办? protected 主要特征是子类,因此外部(包)应该(由于范围有限,但仍然是可选的)提供子类的样式,即子包,或者包 A 扩展了包 B,但我们不知道这样的事情。因此,protected 不能在外部是包的顶层(即没有这样的子包)使用全部潜力(主范围是子类范围),但 protected 可以在外部是嵌套类的嵌套类中使用全部潜力是类(即可以是子类):

class ProtectedNestedMain {
    protected static class Inner {
        public static void main(String[] args) {
            System.out.println("Hello from Inner!");
        }
    }
}

请注意,上面所说的“不能充分利用潜力”,因为它不能达到子类范围,仅仅因为没有外部子类,这意味着实际上受保护可以允许这只是一个选择问题,以避免重复包私有的工作(如果外部不可子类化),请参见下文。

我的困惑主要是由 https://docs 中著名的表格引起的。 oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

在此处输入图像描述

如果允许第一级(公共)和第三级(包私有),那么到底如何-不允许在第二级(受保护)之间?

公共支持子类所以容易误导。阅读此表的正确方法是

如果外部具有子类功能,则公共支持子类。

同样的误导也适用于 package-private,package-private 不支持子类(单元格中的 N)并不意味着子类概念适用于外部。

这意味着如果子类功能在外部不可用,我们应该忽略 Subclass 列:

在此处输入图像描述

正如我们现在所看到的,protected 和 package-private 现在都是同一级别( YYN),不再困惑为什么不允许中间级别。总的来说,Java只选择package-private而不是protected以避免混淆(这只是一个选择问题,但protected主要特征是子类,所以package-private更优越),和结果,top-中只允许使用2个访问修饰符等级:

在顶层 - 公共或包私有(无显式修饰符)。

@Nikita Rybak answer has 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.

Four access modifiers, assume the 1st level is public and 4th level is private (based on this table in sequence). The first thing we should know is why class cannot defined as private in top-level.

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.

But nested private class is 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 characteristic is 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):

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.

My confusing is mainly caused by the famous table at https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html:

enter image description here

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 (N in cell) doesn't means subclass concept apply in outer.

That's means we should ignore the Subclass column if subclass feature is not available in outer:

enter image description here

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 characteristic is subclass, so package-private is superior), and the result, only 2 access modifiers allowed in top-level:

At the top level—public, or package-private (no explicit modifier).

淡看悲欢离合 2024-10-03 18:04:30

protected 与 public 不同。 Protected 既具有包级别访问权限,又只能通过继承在包外部访问。如果一个类在包外部 A 继承了其他包中的一个类(通过使用 INHERITANCE 来保护方法),它可以访问该类 B 的方法有受保护的方法,但从该类派生的子类,即 A 无法访问受保护的方法.. public 的情况相反..

示例:

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
}

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..

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
}
谁人与我共长歌 2024-10-03 18:04:30

受保护:仅在包级别可见*。

类被定义保护 --->它无法从外部包扩展(不可见)。

如果它无法扩展,那么将其保持为受保护是没有意义的,因为这样它将成为允许的默认访问。

这同样适用于私有定义的类。

注意:嵌套类或内部类可以定义为受保护私有

*:探索受保护的关键字,对于这个答案,我做得很简洁。

Protected : VISIBLE only to package level*.

class is defined protected ---> it cannot be extended from outside package(not visible).

And if it cannot be extended then it is meaningless to keep it as protected, because then it will become default access which is allowed.

Same applies to private defined classes.

Note : Nested or inner classes can be defined protected or private.

* : Explore protected keyword, for this answer I made it succinct.

如果外部类由 protected 声明,我认为您希望该类只能从同一包及其子类但不同的包访问。但是,不可能为受保护的类创建子类,因为当您编写“class Dog extends Animal”时,由于受保护的“Animal”只能被其子类访问,显然“Dog”不是“Animal”子类。

所以受保护的外部类与(默认)外部类相同!

if a outer class is declared by protected, I think you want the class can be only accessed from same package and its subclass but different packages. However, there is no possible to create subclasses for a protected class, because when you write "class Dog extends Animal", because of protected "Animal" only can be accessed by its subclass, obviously, "Dog" is not "Animal" subclass.

So protected outer class is same with (default) outer class!

煮茶煮酒煮时光 2024-10-03 18:04:30

内部类允许使用 protected 修饰符。但仍然无法从扩展外部类的类内部构造该内部类的实例。只有当构造代码位于同一个包内时,编译器才允许。但是 protected 修饰符对于默认的可访问性有什么区别呢?
因此,从我的角度来看,顶级类上根本不允许使用 protected 修饰符,并且它对于嵌入式类没有意义。

The protected modifier is allowed on an inner class. But still an instance of this inner class cannot be constructed from within a class extending the outer class. Only when the constructing code is within the same package it is allowed by the compiler. But what difference does the protected modifier then make with respect to the default accessibility?
So, from my point of view, the protected modifier is not at all allowed on top-level classes, and it does not make sense on embedded classes.

霞映澄塘 2024-10-03 18:04:30

“受保护”的行为=“默认”的行为+“在任何包的任何子类中使用它”。

无论如何,我们有类的默认访问修饰符,我们可以从 protected 访问修饰符获得的唯一优点是: - 通过子类化在任何包中使用它。但对于子类,父“受保护”类的可见性将是私有的。所以无法访问。基本上,如果您有一个受保护的顶级类,则任何外部类都无法通过子类化它来获得访问权限。所以保护一个顶级类是没有意义的。

behavior of “protected” = behavior of “default”+ “use it in any subclass in any package”.

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.

终止放荡 2024-10-03 18:04:30

@Akash5288 的答案对我来说毫无意义:

如果所有类都允许子类化,那么它将类似于公共访问说明符。

由于没有办法限制此类仅被少数类子类化(我们不能限制类仅被包内/包外的所有可用类中的少数类继承),因此无法使用顶级类的受保护访问说明符。因此这是不允许的。

然后,您可以将相同的逻辑应用于受保护的方法和变量,它们也“类似于公共”。包外部的所有类都可以扩展我们的公共类并使用其受保护的方法。为什么将方法和变量限制在扩展类中可以,但限制整个类就不行? “与公众相似”不是“与公众相同”。我的解释是,允许受保护的类是完全可以的,就像允许受保护的方法是很好的一样。

答案“您不能扩展您无法访问/查看的类”更合乎逻辑。

The answer from @Akash5288 made no sense to me:

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.

榆西 2024-10-03 18:04:30

这个问题的意义在于,JVM 是用 C(Sun JVM)和 C++(oracle JVM)编写的,因此在编译期间,我们将从 java 文件中创建 .class 文件,并且如果我们使用 Protected 关键字声明一个类那么它就不会被JVM访问。

受保护的类不会被 JVM 访问的原因是,受保护的字段只能通过继承在同一个包内或不同的包中访问,而 JVM 并没有以继承类的方式编写。
希望这能满足这个问题:)

同样,顶级类不能是私有的。解释如下:

那么,如果我们定义一个私有类,该类只能在定义它的实体(在我们的例子中是它的包)中访问,会发生什么?

因此,定义对类的私有访问将使其可以在同一个包内进行访问,而默认关键字已经为我们做到了这一点,因此定义私有类没有任何好处,它只会使事情变得模糊。

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.

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 :)

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.

遗忘曾经 2024-10-03 18:04:30

protected 表示该成员可以被同一个包中的任何类访问
以及子类,即使它们位于另一个包中。

例子:

package a;
class parent{
 protected void p();
}
package b;
import a.p;
class child extends parent{
  //you can access method which is protected in the parent in the child 
}
class another extends child {
 //here you can not access the protected method 
}

protected means that the member can be accessed by any class in the same package
and by sub classes even if they are in another packages.

Example:

package a;
class parent{
 protected void p();
}
package b;
import a.p;
class child extends parent{
  //you can access method which is protected in the parent in the child 
}
class another extends child {
 //here you can not access the protected method 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文