2012-04-08 104 views
2

因此,我將這段代碼放在一個文件夾中,這個文件夾是爲了一個項目而停止開發的。但是,對於Java而言,我有幾個問題(並且我知道代碼不能編譯,但這成爲我的一個問題)。類的繼承和鑄造

interface Executable { 
    public int execute (Object o); 
} 

public class Biv implements Executable { 

    public int execute (String s) { 
    System.out.println (s); 
    return s.length(); 
    } 

    public static void main (String[] args) { 
    Executable e = new Biv(); 
    System.out.println( 
     e.execute ("Hello World!")); 
    } 


} 

1)我的第一個問題是與變量e做。它是用可執行對象類型聲明的,但我不明白爲什麼可以用新的Biv對象實例化。這裏發生了什麼,這是什麼意思?

2)錯誤發生在Biv類的execute方法中。這似乎是因爲它期望一個對象而不是一個字符串。然而,你能不能用一個字符串替換一個對象,因爲字符串是對象的一個​​子類?我可以理解,如果你用Object替換了String,它會有一個錯誤(我認爲),但不是它目前如何完成。

回答

2

I don't understand why it can then be instantiated with a new Biv object

由於Biv器具Executable,所以Biv任何實例也是Executable一個實例。

The error is in the execute method within the Biv class

是的,它[Biv]沒有實現execute(Object)。方法execute(String)僅僅是碰巧具有相同名稱的不同方法,因爲它們不具有相同的簽名。任何實現接口Executable的類都必須覆蓋方法execute(Object)

在java中沒有用於覆蓋方法的參數co-variance,因爲它是不安全的。如果你調用e.execute(new Object())會怎麼樣? [其中e引用Biv對象] Biv將不知道如何處理它。

+1

值得注意的是,簽名不一定必須相同;參數類型可能會「鬆動」。例如,如果接口中的方法接受了'String',則可以讓'Biv'中的方法接受'Object'。 – Maxpm 2012-04-08 23:41:34

+0

@Maxpm:事實並非如此。 – Natix 2012-04-08 23:49:29

+0

@natix我站好了。 – Maxpm 2012-04-09 00:32:01

0

你正在看的是Polymorphism,這是面向對象程序的基本概念之一。要回答您的具體問題#2,您需要匹配接口中的方法的類型簽名(它將一個對象作爲參數),然後將其轉換爲字符串。這(鑄造)在Java中是bad practice,但應儘可能避免。

0

你是不是覆蓋Executable方法(這是必需的),你是超載它(名稱相同,不同的參數類型)。

使用@Override註釋,這將有助於突出錯誤:

public class Biv implements Executable { 

    @Override // This will cause an error to be highlighted saying this isn't overriding any method 
    public int execute (String s) { 
    System.out.println (s); 
    return s.length(); 
    } 
} 
1

1)變量e被聲明爲一個可執行文件,是起搏實現接口。這意味着您可以實例化一個Biv,但將其存儲爲可執行文件並將其作爲可執行文件傳遞。該變量現在只能被視爲可執行文件。這是多態性。

2)這是因爲你試圖覆蓋一個函數並添加額外的簽名限制。這違反了Liskov替代原則。對於職能,這個原則基本上規定你應該「承諾不多,不需要更多」。你所做的是通過強制參數成爲一個字符串「需要更多」,當接口說它可以是一個對象。然後,將它與(1)聯繫起來,如果你的main中的Executable對象調用了它的execute()方法,它不應該限制你只傳遞一個String(因爲Executable接口說execute()可以接受一個Object )。

0

Object類實現了toString()方法,因此不需要轉換。改變起搏接收對象,而不是字符串,並以該方法首先調用該對象的toString(),然後獲取字符串的長度:

interface Executable { 
    public int execute (Object o); 
} 

public class Biv implements Executable { 

    public int execute (Object s) { 
     System.out.println (s); 
     return s.toString().length(); 
    } 

    public static void main (String[] args) { 
     Executable e = new Biv(); 
     System.out.println( 
      e.execute ("Hello World!")); 
    } 

} 

然而,這是一般不好的做法,實行命令設計模式與對象爲了有一個方法接受幾種類型的可能參數。最好將參數封裝在Parameter接口後面。

0

首先讓我們來看看這條線:

public class Biv implements Executable

implements Executable表明類Biv可以採取Executable的作用。或者換句話說,Biv具有Executable中所有方法的實現。

這就解釋了爲什麼後來你可以這樣做:

Executable e = new Biv();

Executable類型的變量,並在此之際,我將使用Biv實現這一點。如果Biv實現Executable接口(並聲明它在你的例子中有),那麼這是可以的。

現在讓我們來看看這個例子中出現問題的地方。在可執行的接口包括這種方法declartion:

public int execute (Object o);

這上面說,你可以叫execute,並通過在你喜歡的任何絕對Object。但是你可以通過Bizexecute方法嗎?不,你只能通過String。所以Biz沒有完全滿足界面。

[圓橢圓問題] migth是很好的進一步閱讀。 1