[英]Superclass references to subclass objects
我很困惑:我從學習資源中引用了以下引用(帶有它們出現的部分的標題),但在我看來這些引用相互矛盾。
“它是引用變量的類型——而不是它所引用的對象的類型——決定了哪些成員可以被訪問”
“它是被引用的對象的類型(而不是引用變量的類型)決定了哪個版本的重寫方法將被執行”
對此的任何澄清將不勝感激。
如果 classB 擴展了 ClassA 並且您有:
ClassA a = new ClassB ();
使用a
變量,你只能訪問成員定義ClassA
(或超類ClassA
或接口, ClassA
工具)。 您無法訪問在ClassB
中定義但未在ClassA
定義的成員(除非您將a
為ClassB
)。
但是,調用在ClassB
重寫的ClassA
方法將執行ClassB
方法。
超類引用和子類對象
假設 Child 擴展了 Parent,讓我們看看這個:
Parent obj = new Child();
現在如果我們嘗試使用obj
,我們只能使用 Parent 類中指定的行為(方法)。 我們不能使用 Child 類中的任何新方法。
但是,假設 Parent 和 Child 都有一個方法public String whoAmI()
。
家長:
return "Parent";
孩子:
return "Child";
現在,如果我們運行此代碼:
Parent obj1 = new Child();
Parent obj2 = new Parent();
System.out.println(obj1.whoAmI());
System.out.println(obj2.whoAmI());
輸出:
Child
Parent
所以你只能訪問你引用它的類中的方法(第一個片段中的父級)。 但是如果你在類中重寫了它,它被實例化為(第一個片段中的子),並在子級中重寫父級中的方法,那么調用父級中存在的方法將調用子級中重寫的方法。
看看下面的程序。
class SuperMem{
int i = 90;
int j = 100;
void show(){
System.out.println("parent show..");
System.out.println("Show inside Parent start");
System.out.println(i + " " + j);
System.out.println("Show inside Parent END");
}
}
class submem extends SuperMem{
int i = 10;
int j = 20;
void show(){
System.out.println("Child show ..");
System.out.println("Show inside Child start");
System.out.println(i + " " + j);
System.out.println("Show inside Child END");
}
}
public class SuperMemDemo {
public static void main(String[] args) {
SuperMem m = new SuperMem();
submem s = new submem();
m = s;
System.out.println("i " + m.i);
System.out.println("j " + m.j);
m.show();
}
}
輸出:
i 90
j 100
Child show ..
Show inside Child start
10 20
Show inside Child END
方法是通過動態分派方法解決的,即在運行時。 分析輸出,您將從完整參考 Herbert Schildt 中獲得上述兩個語句的含義
假設我們有兩個類。
class Vehicle{
public void drive(){
System.out.println("Vehicle is Moving");
}
}
class Car extends Vehicle{
public void drive(){
System.out.println("Car is Moving");
}
public void playMusic(){
System.out.println("Car is Playing Music");
}
}
“它是引用變量的類型——而不是它所引用的對象的類型——決定了哪些成員可以被訪問”
這意味着如果我們有一個像Vehicle vehicle = new Car();
這樣的代碼Vehicle vehicle = new Car();
使用vehicle
對象,我們可以調用drive()
,但不能playMusic()
,因為vehicle
類型是Vehicle
。
“它是被引用的對象的類型(而不是引用變量的類型)決定了將執行哪個版本的重寫方法”
這意味着如果我們有這樣的代碼
Vehicle vehicle = new Car();
vehicle.drive();
它將打印“汽車正在移動”而不是“車輛正在移動”,因為存儲在vehicle
的對象是Car
一個實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.