[英]Java inheritance is Super content copied?
我真的是想了解繼承是如何工作的,
說我們有A和B類,B擴展了A,A包含一些在public和方法上設置的屬性(引用類型和原始類型)
這些屬性和方法是否已復制到B類中? 我確實讀過,這些方法沒有復制,但可以通過引用來訪問。
創建B的實例時繼承的引用類型屬性如何? 它們必須在內存中占用一些空間,該引用存儲在哪里? 在A或B類中? 他們將原始類型復制到B類中,並且它們是否在找到B其他屬性的位置相同?
還是在創建類B的對象時,實際上創建了A和B的對象並且它們保持某種關系?
一些解釋會有所幫助。
假設有一個動物類:
public class Animal {
private String _name;
public Animal(String name) { _name = name;}
public String getName() {return _name;}
}
現在有一個Dog類:
public class Dog extends Animal {
public Dog() {
super("Dog");
}
}
現在,如果您這樣做:
Animal dog = new Dog();
System.out.println(dog.getName());
這是使變量名稱從Dog
類變為Animal
。
Java繼承是復制超級內容嗎?
我真的想了解繼承的原理,
說我們有A和B類,B擴展了A,A包含一些在public和方法上設置的屬性(引用類型和原始類型)
這些屬性和方法是否已復制到B類中?
子類B
繼承了公共屬性和方法。 考慮類A
及其子類B
:
public class A {
public int aNumber = 99;
public StringBuilder aString = new StringBuilder("sb");
private String privateVar = "private stuff";
public A() {
}
public A(int i, StringBuilder s) {
aNumber = i;
aString = s;
}
public int getMyNumber() {
return aNumber*2;
}
public StringBuilder getMyString() {
return aString.append("!!");
}
@Override
public String toString() {
return aNumber + " : " + aString;
}
}
public class B extends A {
public B() {
}
public B(int i, StringBuilder s) {
super(i, s);
}
}
以下類具有一些代碼,可以從繼承方面測試上述兩個類的行為:
public class TestingInheritance {
public static void main(String [] args) {
A a = new A(3, new StringBuilder("test1"));
System.out.println("A: " + a);
B b = new B();
System.out.println("b: " + b);
System.out.println("b.aNumber: " + b.aNumber);
System.out.println("b.getMyNumber: " + b.getMyNumber());
System.out.println("");
B b2 = new B(2, new StringBuilder("xx"));
System.out.println("b2: " + b2);
System.out.println("b2.aString: " + b2.aString);
System.out.println("b2.getMyString: " + b2.getMyString());
//System.out.println("Private: " + b.privateVar);
}
}
輸出:
A: 3 : test1
b: 99 : sb
b.aNumber: 99
b.getMyNumber: 198
b2: 2 : xx
b2.aString: xx
b2.getMyString: xx!!
討論:
有A
和B
兩類。 B
類擴展了A
A
是超類, B
是其子類。 這兩個類分別具有兩個構造函數,一個是默認的無參數構造函數,另一個是帶有參數的構造函數。
類A
具有基本類型和引用類型的公共屬性: int aNumber
和java.lang.StringBuilder aString
。 有公共方法getMyNumber
, getMyString
和java.lang.Object
類的重寫toString
。 注意,還有一個私有變量privateVar
。
來自TestingInheritance
的代碼詳細信息:
(我認為:
B b = new B();
這構造了B
的實例。 這繼承了其超類A
的屬性和方法。
System.out.println("b: " + b); // b: 99 : sb
新創建的對象b
具有從其超類A
繼承的屬性值; 因此,它從覆蓋的toString
方法中打印屬性默認值。 請注意,在類A
為屬性定義的默認值為99
,其字符串值為“ sb”的StringBuilder
對象。
下面使用默認屬性值打印繼承自A
的屬性和方法結果。
System.out.println("b.aNumber: " + b.aNumber); // 99
System.out.println("b.getMyNumber: " + b.getMyNumber()); // 198
(ii)考慮:
B b2 = new B(2, new StringBuilder("xx"));
這將使用提供的參數2
和new StringBuilder("xx")
構造B
的實例。 注意在類B
的構造函數中,聲明super(i, s)
; 這是必需的。 並且,如果未指定,則會出現編譯時錯誤。
System.out.println("b2: " + b2); // 2 : xx
這將在B
類的構造函數中打印提供的參數值,這些參數值又通過參數super(i, s)
傳遞給A
類的構造函數。 創建B
類的實例(使用構造函數)時, A
類的構造函數將運行, 首先 -請參見super(...)
語句(它是構造函數代碼中的第一條語句)。
下面顯示繼承的屬性值和方法返回值。
System.out.println("b2.aString: " + b2.aString); // xx
System.out.println("b2.getMyString: " + b2.getMyString()); // xx!!
(iii)最后,如果未注釋程序TestingInheritance
,則以下語句將無法編譯。 將會出現錯誤: TestingInheritance.java:18: error: privateVar has private access in A
: TestingInheritance.java:18: error: privateVar has private access in A
。
System.out.println("Private: " + b.privateVar);
但是,可以通過類A
定義的公共方法在B
訪問private屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.