对于我们的内部培训,我使用了精彩的书籍《Smalltalk, Objects and Design (Chamond Liu)》,并重新表述了以下示例。-希望这有所帮助...
“一致性”是什么意思? 设计类型安全的类型层次结构,具有高度可替代的类型。获得这种一致性的关键是基于子类型的一致性。 (我们将在此处高层次地讨论Liskov替换原则(LSP)。)
协变:
假设鸟类以静态类型“一致地”下蛋:
如果Bird类型下蛋,则Bird的子类型是否会下一个Egg子类型?
例如,Duck类型下一个DuckEgg,那么就满足了一致性。
为什么这是一致的?因为在这样的表达式中:
Egg anEgg = aBird.Lay();
引用aBird可以合法地被Bird或Duck实例替换。
我们说返回类型对定义Lay()的类型是协变的。
子类型的重写可能会返回更专业的类型。 => “它们提供更多。”
逆变性:
假设钢琴家可以使用静态类型“一致地”演奏钢琴:
如果钢琴家弹奏钢琴,她能够弹奏大钢琴吗?
难道不应该是大师级钢琴家弹奏大钢琴吗?(请注意,这里有一个转折!)这是不一致的!因为在这样的表达式中:
aPiano.Play(aPianist);
aPiano 不能被 Piano 或 GrandPiano 实例合法替换!大钢琴只能由钢琴大师演奏,钢琴家太普通了!
大钢琴必须能够被更一般的类型演奏,这样才能保持一致。
我们说参数类型反变为定义 Play() 的类型。
子类型的覆盖可能接受更广泛的类型。 => “它们需要更少。”