如果 for 的合约BaseCollection
指定其add
方法可以合法地传递自 的任何对象Entity
,那么继承的add
方法 也UserCollection
应该这样做,否则将违反 LSP。如果原始方法可以与从 派生的任意对象一起使用,则UserCollection
包含仅接受类型对象的重载(而不是覆盖)不会违反 LSP ,尽管重载可能不是特别合适。add
User
add
Entity
如果add
所讨论的方法不是 ,而是类似于setItem(int index, Entity value)
基setItem(int index, User value)
类和派生类中的方法,并且如果合同规定它只保证与从同一个集合中读取的对象一起工作,那么提供读取除了的UserCollection
实例之外永远不会产生任何东西User
,该方法可以在不违反 LSPsetItem
的情况下合法地拒绝所有不是实例的对象。User
如果该setItem
方法要拒绝不是 的实例的所有内容user
,那么具有仅接受的重载user
可能是有用且适当的;即使继承的setItem
方法需要验证value
标识的实例User
,接受该类型参数的重载不会。添加此类重载时最大的警告是应避免使用两个未密封的虚拟方法来执行相同的操作;如果要添加重载,则可能应该覆盖并密封基类方法,以便它将传入的参数转换为类型User
,然后链接到方法的重载版本。
请注意,数组订阅后一种形式的契约和继承;一个类型的变量Animal[]
可以持有对 a 的引用Cat[]
;尝试将任意值存储Animal
到Animal[]
标识 a 的 a 中Cat[]
可能会失败,但任何Animal
读出的 anAnimal[]
都保证“适合”在同一个数组中;这使得代码可以对任意引用类型的数组中的元素进行排序或置换,而无需知道相关数组的类型。