第一个要讨论的例子:
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
"类似于"每个ExtraMethods
或ExtraAttributes
,反之亦然。
我的老师的意见是"是A"的关系是在父类和子类之间,没有添加任何额外的方法或属性,所以在上面的例子中,Foo
和ExactDuplicate
之间只有一个"是A"的关系。虽然"is Like A"关系是在父类和添加额外方法或属性的子类之间,所以在上面的例子中,Foo
和ExtraMethods
和ExtraAttributes
之间存在"is Like A"关系。
Car
"不像"Vehicle
,它实际上"是a"Vehicle
,而Van
"像a"Car
,因为两者都有一些特征。
那么哪个是正确的,为什么?,我非常感谢你的解释。
如果我老师的观点是正确的,那么仅仅添加属性会使关系成为"is Like A"关系,还是需要添加新的方法才能成为"is Like A"关系?以及这些子类之间的关系(如果存在的话)。
希望我的问题清楚易懂。
任何帮助都将是非常感激的:)
按照惯例,你是对的,老师是错的。
Is-A允许扩展。子进程可以拥有父进程不允许的属性、操作等。从面向对象的角度来看,关键的一点是,在任何情况下,子对象的实例可以用来代替父对象的实例(编辑:是的,我可能应该提到的是称为Liskov替代原则,通常缩写为LSP,以其创始人Barbara Liskov命名)。
is -like- a主要用于描述错误——当有人试图从矩形继承正方形(反之亦然)时,这是一个明显的例子。两者都不是对方的延伸,因为两者都不具备对方的所有特征。这两个都不应该从另一个继承,因为在某种情况下,用一个来代替另一个要么不起作用(被提议的孩子不符合成为父母的要求),要么可能会破坏一些东西(父母允许的改变会破坏孩子的不变量)。