簡體   English   中英

關於動態綁定的困惑

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM