我从Java 1.4(以前的公司)转变为Java 1.6(新公司)。我观察到,在1.4的情况下,大多数专有框架是使用接口和模板模式定义的,而1.6中大多数框架是围绕泛型定义的。
虽然我仍在努力控制Generics,但我的问题是 - 这是一种正确的设计方法吗?接口使您的设计更加灵活/分离。而泛型,实现类型安全并强制您传递特定类型的类。没有真正帮助解耦您的代码。它是否正确?
一个例子 -
public MyWizard extends SignupWizard<SignupSection, SignupObject, SignupListener, SignupView>{
}
相反,如果它是设计将更灵活。
public interface Wizardable{
public SignableSection getSection();
public SignableObject getSignableObject();
...
}
public MyWizard implements Wizardable{
....
}
答案 0 :(得分:4)
我不会说任何东西是泛型与接口,每个都有不同的需求和用途。以原始帖子中提到的方式使用通用参数有多种用途。它允许开发人员定义构成类的字段对象类型的基类。使用它,开发人员可以接受类对象作为参数,他们可以使用反射创建实际对象并设置字段,或者只接受要在第一个位置设置的整个对象。与需要类对象而不是new T()
或类似对象相关的问题称为type erasure。
使用泛型的另一个好处是,在使用超类中的字段或方法时,您不需要一直进行类型转换 - 您个人知道它们的类型,但Java没有将类型信息存储在任何地方。另一个好处是,所有getter / setter方法都可以使用泛型参数,并为其他对象提供更明智的前端,这些对象依赖于您在上述对象中设置专用字段的事实。
使用接口执行与泛型相同的操作的问题是,在返回它们之前需要其他方法来访问专用类型并进行转换(或检查传入类型然后将字段设置为对象)。它使设计变得更加复杂,并没有真正帮助解耦。
正如我在评论中提到的,任何子类都将设置这些类型参数,并且不向用户显示任何内容。因此,您可以拥有类似class MegaSignupWizard extends SignupWizard<MegaSignupSection, MegaSignupObject, MegaSignupListener, MegaSignupView>
的内容,并且一切都保持完全有效,MegaSignupWizard
可以访问类中的专门方法,而无需强制转换。现在这很酷:))
答案 1 :(得分:3)
泛型允许您在常规类型上实现方法,而接口仅定义签名。也许它有时会像Scala的trait
那样被滥用,但主要是它们有两个不同的用途。如果一切都是一个接口,那么将会有很多重复的代码或代理到一些帮助类。
答案 2 :(得分:1)
我注意到许多新框架倾向于使用注释而不是接口,但我没有注意到它们使用泛型而不是接口(无论它意味着什么 - 请解释更多)。
借助泛型,可以减少一些代码重复并提高类型安全性,当您有一个具有泛型类型参数的接口时,相同的接口将适用于许多不同类型。 java.util包中的集合是泛型有用时的一个很好的例子。
在注释的情况下,有时我觉得它们被过度使用并且界面会更好 - 例如,通过界面,很容易知道方法应该采用什么参数 - 但在其他情况下,注释更灵活,更强大。
答案 3 :(得分:1)
我认为它是泛型和接口,因为任何接口都可以使用泛型本身。当你开始使用泛型(抽象)类时,我看到的问题是你失去了使用组合的灵活性。虽然继承没有什么不好,但你必须为它设计并且存在许多陷阱。
答案 4 :(得分:0)
看看Jung2,看看Generics真正强大的地方。基本上,任何对象都可以是顶点或边缘,这使得网络算法中有一些非常有趣的想法。你不能只使用接口来做到这一点。
我不确定你的上述用途看起来也不错。如果你是从一个对象扩展或实现一个接口,你真的不想传递这样的对象。泛型用于实现具有抽象类型的类,如集合,可以对任何事物起作用。如果我通过完全有效的SignupWizard<int, int, int, int>
会怎样?
对于那个特定的想法,也许你确实想要使用接口。有一个定义wizardaction的接口,每个对象实现它,mywizard能够.addaction(int position,wizardaction action)。事实上,这绝对是一个接口问题。
我同意其他人的看法 - 当图书馆需要使用仿制药时。