您是否将子类对象分配给 Superclass 实例类型仅用于覆盖?还是我们这样做也是为了别的?
示例:Sub 是 Super 的子类型,并且
Super s = new Sub();
请解释。
当有人编写这样的代码时,他/她正试图遵循基本的 OO 设计原则,即:
编程到一个接口,而不是一个具体的实现
我已经在我的一篇博文中解释了这一原则。看Class Inheritance VS Interface Inheritance
部分。
总结这篇文章,当您使用父类型的引用来引用子类型的实例时,您会获得很大的灵活性。例如,如果您将来需要更改子类型的实现,您将能够轻松地做到这一点,而无需更改大部分代码。
考虑以下方法 -
public void DoSomeStuff(Super s) {
s.someMethod();
}
并调用此方法 -
DoSomeStuff(new Sub());
现在,如果您需要更改 内部的逻辑someMethod
,您可以轻松地通过声明 的新子类型Super
,例如NewSubType
,并更改该实现内部的逻辑来实现。这样,您将永远不必接触使用该方法的其他现有代码。您仍然可以通过DoSomeStuff
以下方式使用您的方法 -
DoSomeStuff(new NewSubType());
如果您将参数声明为DoSomeStuff
of Sub
,那么您也必须更改其实现 -
DoSomeStuff(NewSubType s) {
s.someMethod();
}
它也可能链接/冒泡到其他几个地方。
是的,但“压倒一切”不是我会使用的术语。通常,拥有类层次结构的原因不是为了改变超类的行为,而是为了实现它。通常情况下,超类要么是接口,而不是类,要么是遵循模板方法模式的抽象类,其中一些方法保持抽象,多个子类实现这些方法,但一般行为已经固定。
更具体地说,如果我们像您的示例中那样将子类分配给超类实例变量,我们希望在交换子类的情况下限制对代码的影响(我们只需要编辑一行!)