[英]Confusion about dynamic binding
正如我從一本教科書中學到的,如果我將一個超類類型的變量名newObject
分配給子類類型的對象,並且該子類具有一些重寫方法,即方法toString()
,那么當我調用newObject.toString()
,則會調用覆蓋的方法,而不是原始方法。
但是在另一種情況下,我沒有再次發生這種情況。 例如,我的超類名為Ship
,其子類CruiseShip
。
class Ship{}
class CruiseShip extends Ship implements Serializable {
int getSize() {
return 42;// value is not important now
}
}
我序列化CruiseShip
實例,然后反序列化它。
CruiseShip cs = new CruiseShip();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(cs);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
baos.toByteArray()));
Object obj = ois.readObject();
ois.close();
現在返回對象的類型為Object
,所以我將類型轉換為Ship
,以便可以將其分配給變量名稱newShip
,其類型為Ship
。
Ship newShip = (Ship)obj;
問題是我無法調用類CuiseShip
方法,即getSize()
,
int size = newShip.getSize();//error: method getSize() is undefined for the type Ship
這在超類Ship
沒有定義。 只有在將對象類型轉換為CruiseShip
,我才能調用該方法。
int size = ((CruiseShip)newShip).getSize();//OK
那么,這里發生了什么? 我期望動態綁定將允許我使用newShip
調用方法getSize()
,但事實並非如此。
這不是動態綁定的工作原理。 如果該方法在超類存在,並且在子類中被覆蓋稱為聲明類型的超類對象上,然后連的時候,如果它實際上是一個類型的子類 的子類比的方法將被調用的。 但是,如果該方法未在超類中定義,則無法從聲明為該類型的對象中調用該方法。 否則,這沒有任何意義-如果對象不是子類類型而是僅超類類型,該怎么辦-這將是類型錯誤。
如果您無法在超類中實現該方法,則要么您沒有在其中進行動態綁定適用的示例,要么您的超類實際上應該是接口或抽象。
例如:
class Animal
{
void Eat(){
System.out.println("Yum!");
}
}
class Dog extends Animal
{
void Eat(){
System.out.println("Arf!");
}
}
現在,如果你寫
Animal rex = new Dog();
rex.Eat();
輸出將是“ Arf!”。
但是,如果您將class Dog
更改為
class Dog extends Animal
{
void Eat(){
System.out.println("Arf!");
}
void Bark(){
System.out.println("Woof!");
}
}
和寫
Animal rex = new Dog();
rex.Bark();
您會收到一個錯誤-動物不能吠叫。 實際上,如果雷克斯曾經是一條魚,那真的沒有道理。
這是預期的行為。
父母(例如希普)對孩子一無所知。 您可以有成千上萬個不同的類,它們都是Ship的子級。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.