無意中發現的這個有趣的問題。
觀察下列代碼, 父類和子類中都定義有 String name變量,那最終繼承之後是不是隻剩下1個name?還是父類子類的name互相不相干?
通過賦值後,最後會輸出什麼?見如下
public class Son extends Parent{
String name; // 子類中的name
void value(){
name ="a";
super.value(); //調用父類中的value(),給name賦值b
System.out.println(name); //結果輸出 a
System.out.println(super.name); //結果輸出 b
}
public static void main (String[] args){
TestTest test =new TestTest();
test.value();
}
}//end class
class Parent{<span style="white-space:pre"> </span> //定義父類
String name; //父類中的name
void value (){
name = "b";
}
}//end class
輸出:
a
b
由此可見,子類首先 name=“a”,即使調用了父類value()中的 name ="b",
System.out.println(name); 仍然是輸出 a ,可見子類通過引用父類方法並不改變子類中的name的值,即使賦值的變量名都是name
然而,改變的是父類中自己的name變量,因此System.out.println(super.name);輸出 b
綜合得知,父類與子類定義同名的變量,並不會覆蓋,而是各自還有自己的空間,即使變量名相同
子類中調用父類的對同名變量name賦值的方法,仍然只是改變父類自己的name變量的值
再看一個,結合父類引用,多態問題
public class Son_test extends Parent
{
int i = 10;
public static void main(String[] args)
{
Son_test son_test = new Son_test();
System.out.println("son.i=" + son_test.i);//輸出子類的 i=10;
son_test.set(100); // 調用繼承的父類方法,由上可知,改變的只是父類自己的 i
System.out.println("son.i=" + son_test.i); // 輸出的仍然是 子類的 i=10
Parent son =son_test; // 多態,子類對象賦值給父類引用, 引用類型是父類Parent
System.out.println( son.i); // 輸出的竟然是父類的 i=100 ,,,,,,,
}
}
class Parent
{
int i = 10;
public void set(int i)
{
this.i = i;
}
}
輸出:son.i=10
son.i=10
100
由此可見,當父類子類存在同名變量時,引用類型是父類,即使是子類的對象,son.i 中的 i 卻是 父類中的 i 。
分界線
我們知道,如 Parent a = new Son(); 其中son的父類是parent, 利用引用 a.變量 或者 a.方法時候,即使son類中有對應的變量或方法,而父類parent 中沒有a.變量 或者 a.方法,是不能通過編譯的,
但若父類parent 中存在對應的 變量和方法 ,son子類中也有同名的變量和方法, 則a.方法 調用的是子類的方法,而 a.變量 調用的確是 父類的變量。
見如下代碼
public class A {
Animal animals = new Dog();
Dog dogs = new Dog();
public static void main(String[] args) {
A as =new A();
as.go2();
}
void go2(){
animals.eat(); // Animal animals =new Dog(),父類應用類型,子類對象
System.out.println(animals.i);
}
//內部類
class Animal {
int i=10; //子類的i
void eat() {
System.out.println("animal are eating");
}
}
class Dog extends Animal {
int i=100; //父類的i
void eat() {
System.out.println("dogs are eating");
}
}
輸出:
dogs are eating ( animal.eat() 調用的是子類的 eat() )
10 ( animal.i 調用的是父類的 i )