我什么时候应该使用generics来定义类型之间的关系?
在这里使用generics时会产生一些混乱。 我看过Java Generics? 但还是有几个问题。
说我有:
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 car; . . public Person(T c){ car = c; } }
还是取决于执行的任务?
generics仅用于聚合关系(容器等); 他们只是用于collections吗?
一个人通常不参与某种类型的汽车。 他们的汽车只定义了非常讨厌的人。 人们也会改变汽车(及时)。 所以我不会参数化类,如果只是语义。
在进入这样的编程细节之前,考虑一下你试图从现实世界中模仿的东西。
区别并不总是明确的,但这里有一些线索:
- 尝试将它们视为“类型参数”(它们是什么。)它们与类相关联,但它们不一定与它相关。 (例如,查看集合框架。)
- 只有在对象的整个生命周期内不更改类型参数时,才能使用它们。 这听起来很明显,但决定何时不使用generics是一个非常方便的规则。 (例如可以改变汽车的人。)
- 另一方面,如果没有多少实例将使用type参数,如果它太可选,那也不是一个好主意。 (很多人可能根本没有车。)
最后,一般认为我觉得非常有用:如果你不确定,不要害怕原型。 双向编写代码并检查哪一个看起来更简单,更容易理解。 在没有任何解释的情况下将其显示给其他人,或者等待一两天,然后自己重新阅读代码。 然后扔掉另一个。 扔掉代码很好。
如果您有任何方法可以获取或返回涉及T的任何内容,或者其他人可以访问您的car
领域,则需要使用generics版本。 (由于你没有显示任何方法,我们无法说出来。)
例如,使用generics版本,您可以使用类似T someMethod();
然后,当有人拥有一个Person
,他们知道当他们打电话给某个方法时他们可以让Honda
回来,而不是如果你没有仿制药那么一些未知类型的汽车。
类似地,使用generics版本,您可以使用void anotherMethod(T anotherCar);
,当有人拥有一个Person
,这迫使他们将Honda
传递给这种方法,而不是任何一辆车。
所以基本上,拥有一个generics类允许你稍后对对象的使用施加约束(方法调用等)。 如果构造函数是你使用T的唯一地方,并且你不需要在任何方法或字段中使用T,那么是的,没有意义。
这与使用inheritance与组合有关。
在不知道任何其他语义的情况下,Composition似乎更具相关性。 一个人可以改变汽车,而不会成为一个不同的人。
http://www.artima.com/objectsandjava/webuscript/CompoInherit1.html http://en.wikipedia.org/wiki/Composition_over_inheritance
我倾向于喜欢组合(你称之为动态绑定),特别是在你使用的情况下。 一个人不是一种ICar,所以在这里使用仿制药有点奇怪(无论如何)。 我使用generics作为说“ICar的容器”的方式,就像在Garage中一样,尽管在这种情况下我可能只使用集合类型作为变量,或者如果真的需要扩展集合类型。
我建议首先关注语义:
假设您可能有一个Bmw
和一个实施ICar
界面的Toyota
课程,那么就提出这个问题:一个Person
可以改变他的汽车,或者如果他这样做,他会是一个不同的人吗?
如果出于某种原因需要在现有人员实例中将car
属性的值从Toyota
更改为Bmw
,则generics方法将强制您创建新的Person
实例,因此,此新人将与前一个人不同。 当然,您可以将第一个Person
实例创建为Person
而不是将其挂钩到特定的汽车类,但是,为什么要使用generics呢?