2012-07-14 48 views
1

如果我有幾個子類型,每個繼承一個抽象超類和這個超類實現一個接口 - 實現動態綁定/多態時,是否有區別聲明對象作爲超類的類型,反對接口類型?多態/動態綁定,超類還是接口?

所以A,B,C,D選自S延伸和S實現了一

我可以這樣做:

S a = new A(); 
S b = new B(); 

I a = new A(); 
I b = new B(); 

我傾向於使用接口,但我突然想知道如果更好地使用超類,以防將接口分成兩個接口......

+1

它幾乎總是更好的變量聲明爲接口類型,讓你更多的靈活性。否則,您將具體類型限制爲僅限於超類。如果以後要使用完全不同的模擬類來進行測試呢?如果你使用超類,你可能會被卡住。 – 2012-07-14 01:10:26

+1

如果抽象超補充的東西,你需要一個沒有在接口引用,如或接口未列出的方法,你將需要引用,將它們放置在超類型的變量的字段。 如果您不需要超類提供的任何額外功能,請使用界面。 如果父沒有提供任何新的功能可言,你不需要它,你應該讓A和B直接實現我。 – CosmicComputer 2012-07-14 01:16:01

回答

2

從打字角度看,沒有區別。 (除非在運行時使用反射來反省類型,否則特意「去尋找」...)

從運行時性能角度來看,沒有區別。 (除了加載類的時間有一些可能的細微差別...在所有實際使用情況下都可以忽略)

從代碼實現的角度來看,兩種方法都有優點和缺點:

如果您僅使用超類(無接口),則可能可以編寫更少的代碼。但是翻蓋面是,你的代碼是不靈活:

  • 您正試圖在外部API,以在限制您編寫新的實現能力的方式實現。 java.io.OutputStream類是一個典型的例子。因爲它是一個類,所以您必須創建一個子類才能實現新的流類型,並且您可能會發現必須對該子類進行編碼才能覆蓋您「繼承」的所有基礎結構。

  • 類只能有一個超類的事實進一步限制了您的樹形API層次結構。

  • 客戶必須編碼針對實現類的API更大程度......因爲這是所有有。這限制了程序員改變他/她的想法的能力。


底線:如果特定用例不要求你能夠做這些事情(現在或將來),然後使用接口沒有任何好處。但很少有使用案例真的是這樣。而使用接口的增量實施工作量很小。


我要補充,我不問是否要使用的接口。我猜測接口可以用來強迫某人實現方法(並且從未聲明爲類型)?

嘛啊。但抽象方法也是如此。這不是使用接口的真正意義。真正的問題是,接口:

  • 讓更豐富的類型層次結構是可以利用類,
  • 允許寫入獨立的實現類客戶端代碼。

我只是問使用接口作爲對象類型帶來的多態性有什麼好處?

從打字和性能水平:無 - 見上面。

我想,你可以爭辯說,如果你使用的接口的方式是,它跨越了實現層次結構,那麼你在客戶端有更大的靈活性。我想你可以稱之爲「多態性的好處」。 (相反,如果你的接口層次準確反映您的實現類層次結構,那麼你可能已經不是至少在書面代碼方面取得什麼...。)

然而,多態是達到目的的手段,而不是自己的目標,所以我認爲在抽象意義上詢問「多態性帶來的好處」缺少重點。真正的意義在於設計和實施程序的方式是有意義的,並且會產生可維護的代碼。

+0

我應該補充說,我不問是否使用接口。我猜測接口可以用來強迫某人實現方法(並且從未聲明爲類型)?我只是問使用接口作爲對象類型帶來多態性有什麼好處? – user997112 2012-07-14 01:48:03

1

這完全取決於上下文。

實例化代碼只能訪問可用於聲明變量的接口或類的成員。通常目標是限制實例化代碼導入的內容。如果只需要知道List,則將其聲明爲List。如果它需要ArrayList中的方法,則將其聲明爲ArrayList。不要讓實例化代碼知道比它需要的更多。