2011-03-29 56 views
5

假設你有一個Shape基類和各種派生類型:Circle上溯造型使得當對象

是否有過任何理由做一個新的對象時,通過寫這上溯造型在那裏:

Shape s = new Circle(); 

,而不是這樣的:

Circle s = new Circle(); 

,並由各這兩個語句所做的s對象以任何方式從各個不同的其他?

回答

3

就JVM而言,這兩個語句將產生相同的對象。顯示您只打算將該對象用於基類或接口並不罕見。例如。這是常見的:

List<String> list = new ArrayList<String>(); 

雖然一般不是一個好主意,你可以施放Shape回爲Circle,如果你肯定知道,這是一個,例如與Shape s你可以把它帶回一個Circle c有:

if (s instanceof Circle) { 
    Circle c = (Circle) s; 
    // handle Circle case 
} 
0

沒有,對象本身沒有什麼兩樣。只有編譯器認爲他看到的是不同的(例如,哪些方法可用)。

這樣做一個演員的一個原因是表達你喜歡如何對待對象(以便您可以輕鬆插入不同的派生類)。

-2

Circle s = new Circle();
這裏的對象是指類Cricle

Shape s = new Circle(); 這裏它的對象是指接口

兩者都是一樣的。

3

即使Shape可能是一個抽象的或者甚至是一個具體的基類,你也可以爭辯說,你的第一個例子(即Shape s = new Circle();)與「編碼到接口」可以有相同的優點。例如,如果您只使用Shape上定義的方法而不是Circle中特定的方法,那麼只需更改一行代碼(例如Shape s = new Square();),就可以輕鬆地將您正在使用的實現更改爲Square。

對象在你的兩個例子中都是一樣的,第一個選項可以被認爲更好的原因更多的是風格的東西。編碼到接口可以使代碼庫更容易擴展和修改。

1

實例化的對象完全相同。

一個向上轉型的後果是:

  1. 一般化,同時存儲:不同的專門類型的所有對象可以threated爲相同的接口,並且可以存儲在一起成爲數據結構。(像@ WhiteFang34指出的:List < Shape>)
  2. 訪問對象時的泛化方法:客戶端類可以在不知道真實類型的情況下調用Shape的方法(通常,您可以使用工廠創建的對象返回公共接口Shape ,因此客戶端類不知道對象的實際類型,但僅顯示Shape的接口方法)
1

在回答你的問題時,兩個對象是完全相同的。這兩個引用可以在同一個對象指向:

Circle c = new Circle(); 
Shape s = c; 

編碼,接口可以讓你改變實現類與您的代碼的影響降到最低。假設你有這樣的:

Set<String> names = new HashSet<String>();   // using Set reference not HashSet 
names.add("Frank"); 
names.add("John"); 
names.add("Larry"); 

for(String name: names) { 
    System.out.println(name + " is in the team"); 
} 

現在你的需求的變化,你想按字母順序,即用它代替TreeSet的HashSet的要打印的名稱。因爲你已編碼的接口,而不是使用特定於HashSet的類中的任何方法,你只需要改變一個行:

Set<String> names = new TreeSet<String>(); // the only line of code that changes 
names.add("Frank"); 
names.add("John"); 
names.add("Larry"); 

for(String name: names) { 
    System.out.println(name + " is in the team"); 
} 

接口還可以讓你使用依賴注入。它允許您使用編寫代碼時可能不存在的類。

http://en.wikipedia.org/wiki/Dependency_injection