2010-01-23 96 views
2

使用基元和它們的包裝器我理解了擴展的概念。但就其他對象而言,我對擴展和隱式Casting感到困惑。作爲例子與參考投射混淆並在java中擴展w.r.t對象

 Class Animal{ 
     } 

     Class Dog extends Animal{ 

     public static void main(args String[]){ 

     Dog d = new Dog(); 
     d.go(d); 
     } 

     void go(Animal a){ } 
     } 

編輯:問題是哪一個是首選的擴大或鑄造,爲什麼?

+2

問題是? – 2010-01-23 13:19:52

回答

1

(在我看來)如果不需要鑄造,那麼不要這樣做。您的代碼將更具可讀性。

尤其是語法:

d.go(d); 

更加簡潔,而且同樣正確的,因爲

d.go((Animal)d); 

基本上採取的原因擴大優勢下面我介紹我的第一次嘗試回答你的問題。


那麼,這取決於你想要代碼完成什麼。

如果你想要一個功能,可以處理任何種類的動物,狗或其他,那麼你應該把一個動物作爲輸入。

如果你想要一個只需要狗只有的東西的功能,或者只有把狗作爲輸入的操作纔有意義,那麼你應該把狗當作輸入。

編輯:也許一個更人爲的例子將說明爲什麼這不是一個簡單的無反義答案的問題。在Java中,所有對象都是Object的子對象,因此,可以編寫任何方法以使其參數爲Object foo

有時候這可能是有用的,但它的使用情況確實非常嚴格,您僅限於Object上定義的方法。

假設你知道的是Dog,這也是Object。作爲Object而不是通過Dog的實例,您可能想要獲得一些屬性特定的Dog。基本上,如果您需要確保某個函數的參數符合某個契約,那麼您應該將參數限制爲符合的類型 - 略有不同:如果您需要知道它是一個Dog將其聲明爲Dog

作爲一般規則,您應該(在我看來)選擇符合您需要履行的任何合同的「最寬」類型。 如果你需要知道它是一個動物聲明它是一個動物

+0

我不明白你想說什麼。我在上面的例子中問了哪一個是prefererd。 – GuruKulki 2010-01-23 13:29:00

+0

@gurukulki,任何「偏好」取決於你的代碼需要完成什麼(這裏沒有普遍的答案)。我舉了什麼時候擴大優先的例子,什麼時候狹窄是首選。 – 2010-01-23 13:33:18

+0

但我問什麼時候擴張是先發制人,並且首選是鑄造 – GuruKulki 2010-01-23 13:34:57

0

我同意馬克的看法。我使用的經驗法則基本上只是說聲明類型轉換爲子類型是「不好」的。所以,如果某處你的方法

void go(Animal a){ ... }

你需要像

Dog d = (Dog) a;

鑄造你絕對應該(如果可能)改變的Animal類型的參數類型狗的參數。如果該方法適用於所有Animal的子類型而沒有投射,則保持原樣。