最近遇到個很有意思的問題,原來一直沒太注意。這個問題是面向對象的訪問控制是基於class還是對象。先寫個例子。現在有個一類A如下:
class A {
private String str;
public A(String str) {
this.str = str;
}
public void print(A a) {
a.private_method();
}
private void private_method() {
System.out.println(str);
}
}
在方法裏調用如下:
public static void main(String[] args) {
A a1 = new A("a1");
A a2 = new A("a2");
a2.print(a1);
a1.print(a2);
}
這麼做編譯通過,並且順利執行。這就出現了一個很有意思的現象,實例a1和a2都能調用對方的private_method()方法。無論是Java還是C++,都是這樣的情況。
從程序的實現角度來說,調用方法和類屬性的本質,是通過“特徵”在對象所加載的堆區尋找合適的方法和屬性。而“特徵”則是由class模板定義的,所以無論根據同一個class模板new出多少個新對象,所包含的“特徵”都是相同的。這就是訪問控制是根據class來而不是Object來的。參考了JDK的文檔,的確也是這麼說的。
針對剛剛的例子略做修改就更容易理解了:
class A {
private String str;
public A(String str) {
this.str = str;
}
public static void print(A a) {
a.private_method();
}
private void private_method() {
System.out.println(str);
}
}
調用如下:
public static void main(String[] args) {
A a1 = new A("a1");
A a2 = new A("a2");
A.print(a1);
A.print(a2);
}
這樣就可以很清楚的知道,訪問權限的控制是基於class的了。