获得受保护的.链接使用的哪些差异(父母或孩子)?

gst*_*low 0 java scope

请帮我解决这个问题:

考虑这段代码

import java.util.Observable;
import java.util.Observer;

public class MyObservable extends Observable {
    int k;
    public int getK() {
        return k;
    }

    public void setK(int k) {
        this.k = k;
        setChanged();   //valid
    }

    public static  void   main(String [] args){
        Observable observable = new MyObservable();

        Observer myObserver1 = new MyObserver();
        Observer myObserver2 = new MyObserver();

        observable.addObserver(myObserver1);
        observable.addObserver(myObserver2);

        observable.setChanged(); //compilation error here
        observable.notifyObservers();
    }
}
Run Code Online (Sandbox Code Playgroud)

setChanged()从公共方法(它是有效的)和公共静态方法调用 (它是无效的(我看到消息,它是受保护的方法,它不是vald)).我认为静态/非静态不会影响访问.

我不明白为什么.

我在等你正确的解释.

我想知道为什么java创始人做到了这一点?我的变体在概念上有什么错误?

Jon*_*eet 5

它不是真正的静态/非静态差异 - 它是您尝试调用该方法的引用的编译时类型的差异.

在实例方法中,您隐式调用它this,其编译时类型为MyObservable.在main,你在类型的引用上调用它Observable,并且由于protected访问的工作方式,你不能这样做.

从JLS,第6.6.2节(最近的重点是我的):

受保护的成员或对象的构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明它.

6.6.2.1.访问受保护的会员

设C是声明受保护成员的类.仅允许在C的子类S的主体内访问.

此外,如果Id表示实例字段或实例方法,则:

  • 如果访问是通过限定名称Q.Id,其中Q是ExpressionName,则当且仅当表达式Q的类型是S或S的子类时才允许访问.

  • 如果访问是通过字段访问表达式E.Id,其中E是主表达式,或通过方法调用表达式E.Id(...),其中E是主表达式,则允许访问当且仅当如果E的类型是S或S的子类.

因此,在这种情况下,如果更改声明的类型observableMyObservable,你会发现错误消失.