为什么Java中没有子类可见性修饰符?
我不止一次发现自己想要一种在 Java 中不可能实现的变量可见性。我希望某些成员在他们自己的类和任何子类中可见,但对包的其余部分或世界的其他部分不可见。换句话说,我想要这个:
Modifier Class Package Subclass World
sub-class Y N Y N
然而,Java的设计者只给了我 this:
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
我想要这样的东西的典型情况是创建抽象类时。有时我发现抽象父级需要访问某些成员,但具体子级也需要访问某些成员。我可以通过将成员设置为受保护来授予他们此访问权限,但是当我并不真正想要时,这会打开对包其余部分的访问权限。
完全清楚的是,我知道这样的修饰符在 Java 中不可能。我的问题是为什么Java中不包含这样的修饰符? (对我来说)这似乎是比 protected
或默认级别更自然的可见性级别。原因是否只是因为它不够重要而不能被包含在内,或者它是否与我没有考虑到的可能的副作用更相关?
On more than one occasion I have found myself desiring a variable visibility that is not possible in Java. I wanted certain members to be visible within their own class and within any sub-classes, but not to the rest of the package or to the rest of the world. In other words, I wanted this:
Modifier Class Package Subclass World
sub-class Y N Y N
However, the designers of Java only gave me this:
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
The typical case when I want something like this is when creating an abstract class. Sometimes I find the abstract parent needs access to certain members, but concrete children do as well. I can give them this access by making the members protected
, but that opens up accessibility to the rest of the package when I don't really want to.
To be fully clear, I know such a modifier is not possible in Java. My question is why is such a modifier not included in Java? It seems (to me) to be a more natural visibility level than either protected
or the default. Is the reason just along the lines of it not being sufficiently important to be included, or is it more related to possible side effects that I haven't considered?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想他们希望通过非线性访问层次结构来避免增加复杂性。
您应该控制您的包,因此不要在那里调用这些受保护的方法。
(顺便说一句,
protected
与子类和包
不太一样,因为非静态受保护方法(如果不在同一个包中)不能调用声明类的任意对象,但只能调用代码所在子类的对象。(您可以在Object.clone()
上看到这一点,它只能由其对象所在的类调用正在被克隆。))I suppose they want to avoid the added complexity by having a non-linear access hierarchy.
You should have control over your package, so simply don't call these protected methods there.
(By the way,
protected
is not quite the same assub-class and package
, as non-static protected methods (if not in the same package) can't be called on arbitrary objects of the declaring class, but only on objects of the subclass the code is in. (You can see this onObject.clone()
, which can only be called by the class whose object is being cloned.))存在于同一个包中被简单地认为是比存在于子类型更紧密的关系。
为什么?
您通常可以控制正在开发的软件包的所有源代码(*),因此您至少有可能避免进行错误调用。
您无法控制扩展您的类的所有代码。 (任何人都可以扩展您的类。)这意味着包私有访问扮演着更重要的角色。
*) 但是,嘿,我可以使用
package com.yourpackage;
启动任何源文件,这样您就不必控制包中的所有代码!嗯,是的,但是 a) 你实际上不应该这样做,b) 它可以通过 密封包装。Being-in-the-same-package is simply considered a closer relationship than being-a-subtype-of.
Why?
You typically control all source code of the package you're developing(*), so you at least have the possibility to avoid making erroneous calls.
You do not control all code that extends your classes. (Anyone can extend your class.) This means that package private access plays a more important role.
*) But hey, I can start any source file with
package com.yourpackage;
so you don't control all code in your package! Well, yes, but a) you're not really supposed to do that, and b) it can be prevented by sealing the packages.您应该将您的类放入其自己的包中,并将成员(实例变量或方法)标记为受保护。
这样,除了子类之外,没有其他类可以访问您标记为受保护的成员。
如果您迫切希望只让子类访问该受保护的成员,那么您最终将在一个包中得到一个类。
You should put your class in a package of its own and mark the member (instance variable or method) as protected.
This way, no other classes, except the subclasses, can access that member which you marked as protected.
You will end up with one class in one package, if you desperately want only subclasses to access that protected member.