你了解泛化。
关联可以是聚合或组合(或两者都不是)。这是 Tom Pender 曾经使用的一个很好的例子。假设你有一个 Car 类。那个 Car 类“有”一个方向盘、座椅、两个车轴、四个轮子,等等。如果您在制造商环境中创建汽车,那么所有这些之间的关系将是组合:汽车所有部件(在您的制造商处)的寿命与汽车的寿命相关。从制造商的角度来看,当您将汽车交付给经销商时,汽车及其所有部件的使用寿命就结束了。
现在,假设您是垃圾场的所有者。在这种情况下,汽车仍然“拥有”所有这些零件,但它们有自己的生命周期:您可以从汽车上出售零件,如果需要,甚至可以将它们制成其他汽车的一部分。汽车与这些零件之间的关系是聚合,因为零件的寿命与汽车本身的寿命无关。
因此,您可以看到实际上可以根据上下文以两种不同的方式对同一辆车进行建模。
对于抽象类:抽象类只是一个定义方法和/或属性的类,同时要求它们只能在子类中实现。用接口解释为什么是最容易的。接口是抽象类,附加条件是没有一个方法或属性可以直接在类中实现(您可能会说它是如何定义子类的定义)。这就是它们有用的地方。
假设我想定义一个 Animal 类。动物做什么?好吧,他们移动了。他们咬人。 (当然,它们也做其他事情,但让我们坚持使用移动和咬咬。)如果我创建一个动物界面,我会说“这就是动物所做的事情。如果你想成为动物,你也必须这样做这些东西。但是,我不会告诉你如何去做。所以,我创建了一个 iAnimal 接口,它有两个方法,Move 和 Bite。作为一个接口,我不提供任何类型的实现,只是空的过程。
现在,假设我有两只动物,一只跳蚤和一只 TRex。显然,跳蚤和特雷克斯在它们的移动方式或咬合方式上没有任何共同点,但它们两者都有。我会让 Flea 和 TRex 继承或“实现”接口,提供适合动物类型的 Move 和 Bite 实现。
这样做的好处是我的 flea 和 trex 的客户不必知道他们正在处理的是哪一个。他们可以创建一个 iAnimal,根据需要注入 Flea 或 TRex 的实例,并安全地调用 iAnimal 的 Move 和/或 Bite 方法,而不必担心它们是否受支持。 (这就是我们所说的“多态性”)。
所以,接口实现是泛化的一种形式(更准确地说是专业化,反之亦然),正如您可能已经猜到的那样。
从这里开始,“抽象类”就是任何定义了必须继承才能实现的方法或属性的类。因此,正如我所说,接口是抽象类。但是,在一般用法中,抽象类被认为是指不是接口的类,即。 e.一种具有一些具体方法或属性的方法。大多数编程语言都遵循这个定义。