2010-02-24 139 views
8

我從Java 1.4(舊公司)過渡到Java 1.6(新公司)。我觀察到,在1.4的情況下,大多數專有框架都是使用接口和模板模式定義的,而1.6大多數框架是圍繞泛型定義的。泛型與接口

雖然我仍然試圖抓住泛型,我的問題是 - 這是一個正確的設計方法嗎?接口使您的設計更加靈活/分離。泛型,實現類型安全並強制您傳遞特定類型的類。並沒有真正幫助解耦你的代碼。它是否正確?

一個例子 -

public MyWizard extends SignupWizard<SignupSection, SignupObject, SignupListener, SignupView>{ 
} 

,而不是設計將更加靈活,如果它是..

public interface Wizardable{ 
    public SignableSection getSection(); 
    public SignableObject getSignableObject(); 
... 
} 

public MyWizard implements Wizardable{ 
.... 
} 
+1

請改善您的示例。例如什麼是SignupWizard的定義?按照您所談論的方式,使用泛型的框架的一些具體示例。 「泛型與接口」這個問題對我來說沒有多大意義,因爲它們通常都是一起使用的。 「註釋與界面」更有意義。 – 2010-02-24 22:48:33

+0

看起來像我在C++中所期望的那種,而不是Java。 – 2010-02-24 22:52:10

回答

4

我不會說任何東西是泛型與接口,每個人都有他們不同的需求和用途。以原始文章中提到的方式使用泛型參數有多種用途。它允許開發人員定義構成類的字段對象類型的基類。使用這種方法,開發人員可以接受類對象作爲參數,他們可以使用反射來創建實際對象並設置字段,或者接受首先設置的整個對象。這個問題涉及到需要類對象而不是做new T()或這樣的被稱爲type erasure

使用泛型的另一個好處是,當使用超類中的字段或方法時,您不需要一直強調類型轉換 - 您個人知道它們的類型,但是Java沒有將該類型信息存儲在任何地方。另外一個好處是所有的getter/setter方法都可以使用通用參數,併爲其他對象提供更合理的前端,這些對象依賴於您在上述對象中設置專用字段的事實。

使用接口來完成泛型所做的相同事情的問題是,在返回它們(或者檢查傳入類型,然後將字段設置爲對象)之前,您需要其他方法來訪問特定類型並進行轉換。這使得設計變得更加複雜,而且根本沒有幫助解耦。

正如我在評論中提到的,任何子類都將設置這些類型參數,並且不向用戶展示任何內容。因此,您可以擁有類似class MegaSignupWizard extends SignupWizard<MegaSignupSection, MegaSignupObject, MegaSignupListener, MegaSignupView>的東西,並且所有內容都可以完全有效,MegaSignupWizard可以訪問類中的專用方法,而無需投射。現在很酷:)

1

我注意到,許多新的框架傾向於使用註釋,而不是接口,但我沒有注意到他們使用泛型而不是接口(不管它的意思 - 請解釋更多)。

在泛型的幫助下,當您有一個具有泛型類型參數的接口並且相同的接口可用於許多不同類型時,可以減少一些代碼重複並提高類型安全性。 java.util包中的集合是泛型有用的一個很好的例子。

在註釋的情況下,有時我覺得它們被過度使用,並且接口會更好 - 例如使用接口很容易知道方法應該採用什麼參數 - 但在其他情況下,註釋更加靈活和強大。

+0

註解而不是接口?這樣的框架會是什麼? – 2010-02-24 22:43:19

+1

例如Servlet 3.0 API中的@GET註釋:http://today.java.net/article/2008/10/08/introduction-servlet-30 – 2010-02-24 23:39:06

+0

@Murali:曾聽說過JPA?幾乎只有註釋。 – whiskeysierra 2010-02-25 03:47:53

3

泛型允許您在通用類型上實現方法,而接口只定義特徵。也許它有時會像Scala的trait一樣被濫用,但大多它們有兩個不同的用途。如果所有東西都是一個接口,那麼會有很多重複的代碼或委託給一些輔助類。

0

看看Jung2,看看泛型變得真正強大。基本上,任何對象都可以是一個頂點或一條邊,這就使得網絡算法中有一些非常有趣的想法。你不能只用接口來做到這一點。

我不確定您的上述使用看起來不錯。如果你從一個對象擴展或者實現一個接口,你並不想傳遞這樣的對象。泛型被用來實現一個抽象類型的類,就像一個集合,它可以處理任何事情。如果我通過SignupWizard<int, int, int, int>會發生什麼,這是完全有效的?

對於這個特定的想法,也許你想使用接口。有一個定義wizardaction的接口,每個實現它的對象和mywizard都能夠.addaction(int position,wizardaction action)。事實上,這絕對是一個接口問題。

我同意其他人 - 圖書館需要使用泛型。

+0

如果頂點和邊具有超級接口,則對象可以是頂點或邊。 – 2010-02-24 22:47:13

+0

但是你不能在邊上輸入參數。你必須使用對象或堅持一種類型。 – whiskeysierra 2010-02-25 03:49:36

+0

它完全有效。任何子類都將設置這些類型參數並且不向用戶顯示任何內容。因此,您可以擁有像MegaSignupWizard這樣的擴展SignupWizard 的東西,並且MegaSignupWizard可以訪問類中的專用方法而無需投射,所有內容都是完全有效的。 – 2010-03-03 15:27:08

1

我認爲它是泛型和接口,因爲任何接口都可以使用泛型本身。當你開始使用泛型(抽象)類時,我看到的問題會失去使用合成的靈活性。雖然繼承沒有什麼不好,但你必須爲它設計,並且存在許多缺陷。

+0

正確,Bloch在「有效的Java」中的一點是贊成構造而不是繼承。我的理論是,每當我看到泛型和抽象類的大量使用時,程序員都不太熟悉Java中的最新玩具(泛型,註釋)。因此,當我們將所有框架視爲答案時,並不一定意味着這是唯一的方法。只有時間才能證明他們的設計是否可靠並且具有可塑性,也就是說,只要像log4j那樣長。 – michaelok 2014-02-27 23:17:54