Java protected 修饰符未按预期工作
我有以下两个文件:
Fruit.java:
package superClass;
public class Fruit {
protected static void printName() {
System.out.println("My name is Khan");
}
}
Apple.java:
package food;
import superClass.*;
public class Apple {
public static void main(String[] args) {
int i, j;
for(i = 0; i < 5; i++) {
for(j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
printName(); // Call inherited member - NO ERROR, expected
Fruit f = new Fruit();
f.printName(); // Call instantiated member - ERROR, expected
}
}
正如预期的那样,我无法从 Apple 类访问受保护的方法 printName,因为它们驻留在不同的包中。我收到以下错误:
printName() has protected access in superClass.Fruit
完全正确。但是,如果我按如下方式从 superClass 类继承,则不会收到任何错误!
package food;
import superClass.*;
public class Apple extends Fruit {
public static void main(String[] args) {
int i, j;
for(i = 0; i < 5; i++) {
for(j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
printName(); // Call inherited member - NO ERROR, expected
Fruit f = new Fruit();
f.printName(); // Call instantiated member - NO ERROR, WHAT????
}
}
为什么它允许我通过引用访问不同包中另一个类的受保护成员?这应该是非法访问,不是吗?
我很困惑!请有人帮忙。
该代码是使用 Java 1.6.0_18 编译的。
I have the following two files:
Fruit.java:
package superClass;
public class Fruit {
protected static void printName() {
System.out.println("My name is Khan");
}
}
Apple.java:
package food;
import superClass.*;
public class Apple {
public static void main(String[] args) {
int i, j;
for(i = 0; i < 5; i++) {
for(j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
printName(); // Call inherited member - NO ERROR, expected
Fruit f = new Fruit();
f.printName(); // Call instantiated member - ERROR, expected
}
}
As expected, I do not have access to the protected method printName from the class Apple as they reside in different packages. I get the following error:
printName() has protected access in superClass.Fruit
Perfectly correct. But if I inherit from the class superClass as follows I do not get any error!
package food;
import superClass.*;
public class Apple extends Fruit {
public static void main(String[] args) {
int i, j;
for(i = 0; i < 5; i++) {
for(j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
printName(); // Call inherited member - NO ERROR, expected
Fruit f = new Fruit();
f.printName(); // Call instantiated member - NO ERROR, WHAT????
}
}
Why is it allowing me to access the protected member of another class in a different package by reference? This is supposed to be an illegal access, is it not?
I am confused! Someone please help.
The code was compiled using Java 1.6.0_18.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您观察到的行为是因为 printName 是静态的。 protected 修饰符提供了子类中该方法的可见性,但是如果该方法是非静态的,则只能通过子类的实例调用该方法(您提出的问题“如果我如下从类 superClass 继承,我不会收到任何错误!”)。 JLS 第 6.6.2.1 节简洁地定义了这一点。
The behavior you observe is because of the fact that printName is static. The protected modifier provides visibility of that method in the sub-class but if the method is non-static, invocation of that method is possible only through the instance of a sub-class (the concern you were raising "if I inherit from the class superClass as follows I do not get any error!"). The JLS section 6.6.2.1 defines this succinctly.
protected 修饰符允许在继承的类中进行访问。如果您需要限制仅访问某些包中的类,则需要一个“package”修饰符,它只是一个空修饰符,即编写如下方法:
它将具有包可见性。
protected modifier allows access in inherited classes. If you need to restrict access to classes only in certain package you need a "package" modifier, which is just an empty modifier, i.e. write method like this:
and it will have the package visibility.
这是受保护的访问的定义:受保护的成员可以从子类访问,无论其位于不同的包中。
这里引用了Java的访问修饰符 。
注意:在Java中,约定是使用小写的包名称,即
superClass
不遵守此约定。您可能会被这个困扰 - 特别是如果您在文件和目录名区分大小写的 *nix 平台上进行开发。This is the definition of
protected
access:protected
members are accessible from subclasses, regardless of being in a different package.Here is a reference to the access modifiers of Java.
Note: in Java, the convention is to have lowercase package names, i.e.
superClass
is not adhering to this convention. You might be bitten by this - especially if you are developing on *nix platforms where file and directory names are case sensitive.超类的受保护成员可以从子类访问,即使超类位于另一个包中,但我们可以通过引用使用受保护成员的类来使用,因为此时该类是受保护成员的所有者。
假设
i
中的受保护成员是完美的,但a1.i
不完美,给出错误。在 D 类中,我们可以通过 d 的引用而不是 A 类的引用来使用受保护的成员
The protected members of the superclass are accessible from the subclass, even if the superclass is in another package but we can use by reference of that class in which protected member is used because at this time that class is owner of protected member.
Suppose protected member in
i
is perfect buta1.i
is not perfect, give error.In class D we can use protected member by reference of d not reference of class A
即使超类位于另一个包中,子类也可以访问超类的受保护成员。请参阅本页的第二部分和随附的表格/图表:
http ://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html
The
protected
members of the superclass are accessible from the subclass, even if the superclass is in another package. See the second part of this page and accompanying table/diagram:http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html
事情是这样的,当你说
记住 printName 是一个静态方法,所以即使编译器接受这种形式,
真正的形式也永远是
所以最后你得到了继承的静态方法,你只是对如何静态感到困惑方法有效,它们是类方法而不是实例,即使编译器不会抱怨编写表单
内部发生的真正事情是类访问。但可以肯定的是,编译器会给出与此类似的警告:
Here is the thing, when you said
keep in mind that printName is a static method, so even if the compiler accepts the form
The real form will always be
So at the end you get the static method inherited, you are just confused about how static methods works, they are class methods not instance, even if the compiler does not complain about writing the form
The real thing happening inside is class access. But is sure the compiler gives a warning similar to this:
您是否将 protected 与默认(又名包)修饰符混淆了?后者限制对同一包的成员的访问。
Protected 限制对包成员和从相关类继承的类的访问。
请参阅 http://java.sun.com /docs/books/jls/second_edition/html/names.doc.html#62587 了解详细信息
Are you confusing protected with the default (aka package) modifier? The later restricts access to members of the same package.
Protected restricts access to members of the package and classes inheriting from the class in question.
See http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#62587 for details
是的,很好,您没有收到任何错误...这可能违反了 Java 语言规范或错误...无论如何,这是对的。这就是 protected 访问修饰符的定义。 Protected 类似于类成员可从外部或其他类访问的中间级别。我想这是私人和公共之间的事情。受保护的类成员可以(从类的子类)和(从其他类访问,只要它们属于同一个包)。只是一个想法!
Aye, dat's good that you did not get any error... that could have been a violation in the Java language specification or a bug... Anyway, that's right. that's the definition of protected access modifier. Protected is a like an intermediate level of class members' accessibility from the outside or from other classes. that's between private and public i suppose. protected class members are accessible ( from subclasses of a class ) and (from other classes as long as they belong to the same package). just a thought!