18

当使用泛型时,这里有点混乱。我看过Java泛型?但仍有几个问题。

说我有:

public class Honda implements ICar(){
}

public class Opel implements ICar(){
}

我应该使用:

public class Person{
    ICar car;
    .
    .
    public Person (ICar c){
        car = c;
    }
}

或者

public class Person<T extends ICar>{
    T car;
    .
    .
    public Person(T c){
        car = c;
    }
}

还是取决于执行的任务?

仅用于聚合关系(容器等)的泛型;也就是说,它们只是用于收藏吗?

4

6 回答 6

16

一个人通常不会用一种汽车参数化。只有非常讨厌的人是由他们的汽车定义的。人们也(及时)更换汽车。所以我不会参数化类,如果只是为了语义。

在进入这些编程细节之前,想想你试图从现实世界中模仿什么。

于 2012-07-11T16:18:56.660 回答
12

区别并不总是很明确,但这里有一些线索:

  1. 尝试将它们视为“类型参数”(它们是。)它们与类相关联,但不一定与它相关。(以集合框架为例。)
  2. 类型参数只有在对象的整个生命周期内都不会改变时才能使用。这听起来很明显,但它是决定何时不使用泛型的非常方​​便的规则。(例如可以换车的人。)
  3. 另一方面,如果没有多少实例会使用类型参数,如果它太可选,那也不是一个好主意。(很多人可能根本没有汽车。)

最后,我发现一个非常有用的一般想法:如果您不确定,不要害怕制作原型。以两种方式编写代码,并检查哪一种看起来更简单、更容易理解。在没有任何解释的情况下将其展示给其他人,或者可能等待一两天,然后自己重​​新阅读代码。然后把另一个扔掉。丢弃代码是好的。

于 2012-07-11T16:28:52.227 回答
8

如果您有任何方法可以获取或返回任何涉及 T 的内容,或者其他人可以访问您的car字段,则您需要泛型版本。(由于您没有显示任何方法,因此我们无法确定。)

例如,使用泛型版本,您可以拥有类似 的方法T someMethod();,然后当有人拥有 时,他们知道他们可以在调用时Person<Honda>得到返回,而不是如果您没有泛型,则可以得到一些未知类型的汽车。HondasomeMethod

类似地,使用泛型版本,您可以拥有类似 的方法void anotherMethod(T anotherCar);,然后当有人拥有 a 时Person<Honda>,这会强制他们将 a 传递Honda给此方法,而不是任何汽车。

所以基本上,拥有一个泛型类可以让您在以后对对象的使用进行限制(方法调用等)。如果构造函数是您使用 T 的唯一地方,并且您不需要在任何方法或字段中使用 T,那么是的,没有意义。

于 2012-07-11T18:29:55.667 回答
4

这与使用继承与组合有关。

在不知道任何其他语义的情况下,组合似乎更相关。一个人可以换车,但不会变成另一个人。

http://www.artima.com/objectsandjava/webuscript/CompoInherit1.html http://en.wikipedia.org/wiki/Composition_over_inheritance

于 2012-07-11T16:12:53.397 回答
1

我倾向于支持组合(你称之为动态绑定),特别是在你使用的情况下。一个人不是 ICar 的一种,所以在这里使用泛型有点奇怪(无论如何对我来说)。我会使用泛型来表示“ICar 的容器”,就像在 Garage 中一样,尽管在这种情况下,我可能只使用集合类型作为变量,或者如果真的需要扩展集合类型。

于 2012-07-11T16:11:55.343 回答
0

我建议首先关注语义:

假设您可能有一个Bmw和一个Toyota实现ICar接口的类,然后提出这个问题:可以Person改变他的汽车还是如果他这样做会是一个不同的人?

Person如果出于某种原因您需要将现有人员实例中的car属性值从Toyota更改为,泛型方法将强制您创建一个新实例Bmw,因此,这个新人将与前一个不同。当然,您可以创建第一个Person实例,Person<ICar>而不是将其挂钩到特定的汽车类,但是,为什么要使用泛型呢?

于 2012-07-11T16:33:52.310 回答