Java 获得受保护的信息。链接使用了哪些差异(父项或子项)?
请帮我解决这个问题: 考虑一下这个代码Java 获得受保护的信息。链接使用了哪些差异(父项或子项)?,java,scope,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; setChang
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();
}
}
我从public方法(它是有效的)和public静态方法(它是无效的(我看到消息说它是受保护的方法而不是vald))调用setChanged()。我认为静态/非静态对访问没有影响
我不明白为什么
我在等你的正确解释
我想知道为什么java创始人会这样做?在概念上,我的变体有什么错误?这不是真正的静态/非静态差异——它是试图调用方法的引用的编译时类型的不同
在instance方法中,您在this
上隐式调用它,它的编译时类型为MyObservable
。在main
中,您正在对类型为observeable
的引用调用它,但由于受保护的
访问是如何工作的,因此您不能这样做
从JLS(结尾处的重点是我的):
对象的受保护成员或构造函数可以从包的外部访问,在包中它只能由负责该对象实现的代码声明
6.6.2.1。访问受保护的成员
设C为声明受保护成员的类。仅允许在C的子类S的主体内访问
此外,如果Id表示实例字段或实例方法,则:
- 如果访问是通过限定名称Q.Id进行的,其中Q是ExpressionName,则当且仅当表达式Q的类型是S或S的子类时,才允许访问
- 如果访问是通过字段访问表达式E.Id进行的,其中E是主表达式,或者通过方法调用表达式E.Id(…),其中E是主表达式,则当且仅当E的类型是S或S的子类时,才允许访问
因此,在本例中,如果您将声明的observable
类型更改为MyObservable
,您将发现错误消失。这实际上不是静态/非静态差异,而是您试图调用该方法的引用的编译时类型的差异
在instance方法中,您在this
上隐式调用它,它的编译时类型为MyObservable
。在main
中,您正在对类型为observeable
的引用调用它,但由于受保护的
访问是如何工作的,因此您不能这样做
从JLS(结尾处的重点是我的):
对象的受保护成员或构造函数可以从包的外部访问,在包中它只能由负责该对象实现的代码声明
6.6.2.1。访问受保护的成员
设C为声明受保护成员的类。仅允许在C的子类S的主体内访问
此外,如果Id表示实例字段或实例方法,则:
- 如果访问是通过限定名称Q.Id进行的,其中Q是ExpressionName,则当且仅当表达式Q的类型是S或S的子类时,才允许访问
- 如果访问是通过字段访问表达式E.Id进行的,其中E是主表达式,或者通过方法调用表达式E.Id(…),其中E是主表达式,则当且仅当E的类型是S或S的子类时,才允许访问
因此,在这种情况下,如果您将声明的可观察的类型更改为MyObservable
,您会发现错误消失了。这些概念是什么?为什么要做?@gstackoverflow:我不知道你的意思。对不起,英语不好。我不明白禁止这种构造的概念性原因?@gstackoverflow:其思想是类应该只能使用自己类实例的受保护成员。。。一种“有点不完全私密”的感觉。我知道)如果允许使用observable.setChanged()有什么不好?如果把可观察和我可观察放在一个包中,它会起作用,这些概念是什么?为什么要做?@gstackoverflow:我不知道你的意思。对不起,英语不好。我不明白禁止这种构造的概念性原因?@gstackoverflow:其思想是类应该只能使用自己类实例的受保护成员。。。一种“有点不完全私密”的感觉。我知道)如果允许使用observable.setChanged()有什么不好?如果将可观察和可观察放在一个包中,它就会工作