我正在学习 Java 访问修饰符。为此,我创建了一个类Machine:
package udemy.beginner.interfaces;
public class Machine {
public String name;
private int id;
protected String description;
String serialNumber;
public static int count;
public Machine(){
name = "Machine";
count++;
description = "Hello";
}
}
Run Code Online (Sandbox Code Playgroud)
然后,在另一个包中,我创建了一个类Robot作为汽车的子类Machine:
package udemy.beginner.inheritance;
import udemy.beginner.interfaces.Machine;
public class Robot extends Machine {
public Robot(){
Machine mach1 = new Machine();
String name = mach1.name;
//here I am getting error "The field Machine.description is not visible"
String description = mach1.description;
}
}
Run Code Online (Sandbox Code Playgroud)
尝试访问description类中的字段时出现错误Robot。根据我对protected访问修饰符如何工作的理解,它应该没问题,但也许我搞砸了一些事情。有什么想法吗?
编辑:我试图将Robot类移动到与Machine类所在的包相同的包中,现在它可以工作了,而无需使用它。如果有人可以解释我this。根据下面的答案,它不应该工作......
您不能在类的不同实例中访问受保护的超类字段。
有一个很好的理由:您不知道它是否与您具有相同的子类,或者完全不同的子类。如果允许访问受保护的字段,您将被允许访问完全不相关的类的内部。
如果您确定该对象与要访问超类字段的类属于同一子类,则可以强制转换该对象;当您这样做时,您可以访问受保护的字段。
Java 语言规范部分 6.6.2中描述了这些规则
6.6.2. 有关受保护访问的详细信息
对象的受保护成员或构造函数可以从包的外部访问,在该包中仅由负责实现该对象的代码声明它。
6.6.2.1. 访问受保护的成员
设 C 是声明受保护成员的类。只允许在 C 的子类 S 的主体内访问。
此外,如果 Id 表示实例字段或实例方法,则:
- 如果访问是通过限定名称 Q.Id 进行的,其中 Q 是 ExpressionName,则当且仅当表达式 Q 的类型是 S 或 S 的子类时才允许访问。 [这是相关部分]
protected变量可以在类外访问,但只能通过继承访问。因此,如果您将该语句更改为:
public Robot(){
Machine mach1 = new Machine();
String name = mach1.name;
// This will work (access on `this` reference)
String description = this.description;
}
Run Code Online (Sandbox Code Playgroud)
实际上protected修饰符的意思是,该字段是可见的,可以被子类继承,并且只能在那里使用,使用this引用。