|
|
1
21
我不希望如此,因为它会破坏类型暗示合同。假设一个函数
在契约术语中,子类必须遵守其祖先的契约,这意味着函数参数可以得到更基本/更少指定/提供较弱的契约,返回值可以得到更多派生/更多指定/提供更强的契约。这一原则在《埃菲尔铁塔》(可以说是合同语言中最流行的设计)中进行了描述 An Eiffel Tutorial: Inheritance and Contracts contravariance and covariance 分别地
从理论上讲,这是LSP违规的一个例子。不,不是
那个
LSP
Liskov Substitution Principle
,表示子类型的对象可以替换为超类型的对象。
|
|
|
2
4
在回答OP时,公认的答案是正确的,即他试图做的事违反了Liskov替代原则。OP应该利用一个新的接口,使用组合而不是继承来解决他的函数签名问题。OP示例问题中的变化相当小。
上面的代码示例做了两件事:1)创建ISimpleFactory接口,所有依赖于SimpleAttributes工厂的代码都将针对该接口进行编码;2)使用泛型工厂实现SimpleFactory将需要SimpleFactory通过构造函数获取它将在中使用的AbstractFactory派生类的实例ISimpleFactory接口方法中的更新函数在SimpleFactory中重写。 这允许从依赖ISimpleFactory的任何代码封装对泛型工厂的任何依赖,但允许SimpleFactory替换从AbstractFactory派生的任何工厂(满足LSP),而无需更改其任何代码(调用代码将提供依赖)。ISimpleFactory的一个新派生类可能决定不使用任何AbstractFactory派生的实例来实现自己,所有调用代码都将被屏蔽掉该细节。 继承可能有很大的价值,但是,有时组合会被忽略,这是我减少紧耦合的首选方法。 |
|
|
3
1
由于PHP7.4,允许通过使用接口在子类中使用更具体的类型提示
|