"is A" VS "is Like A"关系中,每种关系的含义以及它们有何不同?



第一个要讨论的例子:

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;
};

我和老师讨论了"is a "one_answers"is Like a "的关系,以及它们之间的区别。

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

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

我认为,我的老师定义的"是A"关系并不是真正有用的,因为在大多数情况下,如果没有添加任何东西,就没有理由改变实现。这是一个点。另外,Car"不像"Vehicle,它实际上"是a"Vehicle,而Van"像a"Car,因为两者都有一些特征。

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

如果我老师的观点是正确的,那么仅仅添加属性会使关系成为"is Like A"关系,还是需要添加新的方法才能成为"is Like A"关系?以及这些子类之间的关系(如果存在的话)。

希望我的问题清楚易懂。

任何帮助都将是非常感激的:)

按照惯例,你是对的,老师是错的。

Is-A允许扩展。子进程可以拥有父进程不允许的属性、操作等。从面向对象的角度来看,关键的一点是,在任何情况下,子对象的实例可以用来代替父对象的实例(编辑:是的,我可能应该提到的是称为Liskov替代原则,通常缩写为LSP,以其创始人Barbara Liskov命名)。

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

最新更新