Java - 子类无法访问受保护的字段?

Java - Protected field not accessible from the subclass?

我正在学习 Java 访问修饰符。为此,我创建了一个 class 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";
    }

}

然后,在另一个包中,我创建了一个classRobot作为汽车class的子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; 
    }

}

我在尝试访问 class Robot 中的字段 description 时遇到错误。根据我对 protected 访问修饰符如何工作的理解,它应该没问题,但也许我搞砸了一些东西。有什么想法吗?


编辑:我试图将 Robot class 移动到与 Machine class 相同的包中,现在它可以工作了,不需要使用它.如果有人能给我解释一下this。根据下面的答案,它应该不能正常工作......

您无法在 class.

的不同实例中访问受保护的超级 class 字段

有一个很好的理由:你不知道它有和你一样的subclass,还是完全不同的subclass。如果它被允许访问受保护的字段,您将被允许访问完全不相关的内部 classes.

如果确定该对象与要访问superclass字段的class属于同一个subclass,则可以强制转换该对象;当你这样做时,你可以访问受保护的字段。

规则在Java Language Specification section 6.6.2

中描述

6.6.2. Details on protected Access

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

6.6.2.1. Access to a protected Member

Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.

In addition, if Id denotes an instance field or instance method, then:

  • If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S. [This is the relevant section]

protected 变量可在 class 外部访问,但只能通过继承访问。因此,如果您将该语句更改为:

public Robot(){

    Machine mach1 = new Machine();
    String name = mach1.name;
    // This will work (access on `this` reference)
    String description = this.description; 
}

实际上protected修饰符的意思是,该字段是可见的,可以被子class继承,并且只能在那里使用,使用this引用。