面向对象设计是一个非常棒的概念,但我在如何理解它的大部分方面上感到困惑。我认为好的面向对象设计的关键在于如何看待它。我通常这样看待面向对象:
类是现实世界中的实体或对象
实例字段是实体的属性('有 A')
方法就像动作、动词,是实体的能力
接口就像你可以赋予对象的能力。它也可以是“是 A 或可以做”关系,其实现并不是铁板一块。超人是克里普顿人,作为克里普顿人具备一些特殊能力,比如飞行、冰冻呼吸等。超人的飞行方式与绿灯侠、孙悟空和蝙蝠侠等人不同,因此如果你正在创建一个虚构宇宙,将飞行作为接口可能是个不错的主意。
public class SuperMan extends Man implements Kryptonian{}
public interface Kryptonian extends Flight, FreezeBreath{
public void fly();
public void coolBreath();
}
当你把泛型应用到代码中时,问题就随之而来了。因为类型参数在类/接口和类型之间创建了某种约定。
public interface Flight<T>{
public void fly(T t);
}
在这个例子中,Flight与T耦合,T可以是一个超级英雄、一只鸟或者任何能飞的东西。但这真的是我应该想象的吗?因为这似乎和普通接口做的事情一样?虽然,参数化接口仍然是一个接口,但与类型T的耦合确实让我感到困扰。此外,当你在参数类型上加上有界限制时,事情也变得复杂了起来。
public class Pidgey<T extends Bird> implements Flight<T>{}
您能够将T与哪个真实的具体对象进行关联?上面的例子是相当错误的,虽然使用类参数来限制Flight类型可能是一个好的设计,因为Flight仍然足够独立,其他类可以在没有任何限制的情况下使用它。但是这个例子本身是错误的。Pidgey是一只会飞的鸟,但T可以是任何东西,它可以是另一个对象或能力。问题是它的含义是什么,为什么要把T放在那里?有哪些现实世界的例子呢?
当谈到集合时很容易理解,因为集合就像容器。您可以创建各种不同类型的容器来容纳不同类型的对象。
public class WaterBottle<T extends Liquid> implements UniqueCap{}
但我看到泛型不仅被用于类似容器的对象上,如何设计这样的对象,他们考虑了什么?
public interface Flock<T extends Bird>
的群体接口,其中群体是一组鸟 - 虽然这仍然是一个容器(本质上是)。 - Jared