77

我通常会尝试确保我的对象实例符合Liskov Substitution Principle,但我一直想知道人们是否认为 LSP 也应该适用于构造函数?

我试过用谷歌搜索,但无论哪种方式,我都找不到任何强烈的意见。

我应该注意,我的大部分编码都是用 Ruby 编写的,但有时我会发现我的子类构造函数与父类略有不同。它们采用相同的基本参数集,通常还有额外的参数。有时,其他类方法也会发生这种情况。

在我的脑海里,这一直感觉像是违反了 LSP,但我想看看其他人是否也有这种感觉。

4

3 回答 3

84

不,当您使用构造函数时,您知道您正在处理子类型。这允许您拥有父构造函数不需要的先决条件,例如其他参数。这就是为什么在大多数语言中,构造函数名称是正在创建的类的名称。

一个很好的例子就是 aColoredSquare可能是 的正确子类型Square,但需要一个额外的参数:color。如果你不能做这样的事情,那么子类型的用处就会少得多。

从某种意义上说,构造函数实际上并不是类型的一部分:它是一个返回该类型元素的函数。因此,为子类型定义一个新的构造函数不会破坏 LSP。

于 2011-03-30T19:00:18.387 回答
16

绝对没有。

构造函数通常专门用于子类型。尝试将 LSP 应用于构造函数就像说子类型不能添加特定的方法或成员。但限制只是反过来。

我也同意 Philip 的观点,构造函数并不是类型的一部分(在某些语言中,您可以轻松地使用其他工厂而不是构造函数)。使用 smalltalk 术语,您会说构造函数是元类的方法。

这里没有违反 LSP,它只适用于实例方法,不适用于类方法(构造函数或任何其他类方法)。

于 2011-03-30T20:05:52.163 回答
1

这是一个固执己见的问题,但我倾向于写我的方式是,额外的参数对改变功能没有真正的影响。我的意思是,当我的构造函数在子类中需要一个额外的参数时,它是为了维护标准功能(但做不同的底层事情),这样可以说我创建 ClassA = new ClassB(with some args); 那么无论我这样做还是 ClassA = new ClassA(); 功能都是一样的 我通常使用某种工厂方法来创建它们,因此它们的工作方式是无缝的。这就是我做事的方式,绝不是绝对正确的做事方式。

于 2011-03-30T19:00:03.977 回答