6

先举个例子来讨论:

class Foo
{
    // Attributes:
    int attribute1, attribute2;

    // Methods:
    virtual void Foo1()
    {   /* With or without Implementation   */  }
    virtual void Foo2()
    {   /* Also with or without Implementation */ }
};

class ExactDuplicate: Foo   // No New Attributes or Methods
{   
    virtual void Foo1()
    {   /* A new Implementation */  }

    // Also there might be new Implementations to other methods
};

class ExtraMethods: Foo     // Having New Methods
{
    virtual void Foo3()
    {   /* Implementation   */  }
};

class ExtraAttributes: Foo  // Having New Attributes
{
    int attribute3;
};

我和我的老师讨论了“是 A ”和“就像 A ”的关系以及它们有何不同。

我的意见(我在不记得的地方读过)是“是 A ”关系是父类和继承自它的子类之间的关系,并且不受添加新方法或属性的影响,因此任何实例来自子类 " is A " 的父类,在上面的例子中,每个ExactDuplicate, ExtraMethods, 或ExtraAttributes" is A " Foo。虽然“ is Like A ”关系是从同一个 Parent 类继承的两个 Child 类之间的关系,但在上面的示例中,每个ExactDuplicateis Like ”都是ExtraMethodsor ExtraAttributes,反之亦然。

我的老师的意见是“ is A ”关系是在父类和没有添加任何额外方法或属性的子类之间,所以在上面的例子中,和之间只有一个“ is A ”关系。虽然“is Like A”关系是在父类和添加额外方法或属性的子类之间,所以在上面的示例中,在和之间存在“ is Like A ”关系。FooExactDuplicateFooExtraMethodsExtraAttributes

我认为,我的老师定义的“是 A ”关系并不是很有用,因为在大多数情况下,如果不添加任何内容,就没有理由更改实现。这是一个点。另一个, a Car" is NOT Like a " Vehicle,它实际上是 " is A " Vehicle,而 a Van" is Like A " Car,因为两者都关联了一些特征。

那么哪个是正确的,为什么?,我将非常感谢解释。

另外,如果我的老师的意见是真实的,那么仅添加属性会使关系成为“就像 A ”关系,还是需要添加新方法才能成为“像 A ”关系?什么(如果存在)是子类之间的关系。

希望我的问题清晰易懂。

任何帮助将不胜感激 :)

4

1 回答 1

3

由于这些术语通常被使用,你是对的,你的老师是错的。

Is-A 确实允许扩展。子级可以具有父级不允许的属性、操作等。从 OOP 的角度来看,关键点是在任何情况下都可以使用子实例代替父实例(编辑:是的,我可能应该提到这被称为 Liskov 替换原则,通常缩写为 LSP,以其创始人 Barbara Liskov 的名字命名)。

Is-like-A 主要用于描述错误——例如,当有人试图从矩形继承正方形(反之亦然)时。两者都不是对方的真正延伸,因为两者都没有对方的所有特征。两者都不应该从另一个继承,因为在某些情况下,用一个代替另一个不起作用(提议的孩子不符合作为父母的要求)或可能破坏某些东西(父母允许的更改会破坏孩子的不变量)。

于 2011-10-04T19:48:32.983 回答