可以说我有Python方法重写,签名问题?
class Super():
def method1():
pass
class Sub(Super):
def method1(param1, param2, param3):
stuff
这是正确的吗?将调用method1总是去到子类?我的计划是有2个子类,每个子类都使用不同的参数覆盖method1
可以说我有Python方法重写,签名问题?
class Super():
def method1():
pass
class Sub(Super):
def method1(param1, param2, param3):
stuff
这是正确的吗?将调用method1总是去到子类?我的计划是有2个子类,每个子类都使用不同的参数覆盖method1
在python中,所有的类方法都是“虚拟的”(就C++而言)。所以,在你的代码的情况下,如果你想打电话method1()
超类,它必须是:
class Super():
def method1(self):
pass
class Sub(Super):
def method1(self, param1, param2, param3):
super(Sub, self).method1() # a proxy object, see http://docs.python.org/library/functions.html#super
pass
和方法签名事做。你不能把这样的方法:
sub = Sub()
sub.method1()
Python会允许这样做,但如果method1()
旨在从外部代码执行,那么你可能要重新考虑这一点,因为它违反了LSP等都不会始终正常工作。
是的。调用“method1”将始终转到子类。 Python中的方法签名只包含名称而不包含参数列表。
错误的答案。方法签名总是很重要,因为没有函数重载,因为它发生在C/C++中。 – 2011-05-17 17:33:52
我的意思是,Python不考虑参数列表来决定调用哪种方法,但是我认为从_that_角度看它是正确的! – Elektito 2011-05-17 17:38:08
它将工作:
>>> class Foo(object):
... def Bar(self):
... print 'Foo'
... def Baz(self):
... self.Bar()
...
>>> class Foo2(Foo):
... def Bar(self):
... print 'Foo2'
...
>>> foo = Foo()
>>> foo.Baz()
Foo
>>>
>>> foo2 = Foo2()
>>> foo2.Baz()
Foo2
然而,这一般不建议使用。看看S.Lott的回答:Methods with the same name and different arguments are a code smell。
你可以做这样的事情,如果它是确定使用默认参数:
>>> class Super():
... def method1(self):
... print("Super")
...
>>> class Sub(Super):
... def method1(self, param1="X"):
... super(Sub, self).method1()
... print("Sub" + param1)
...
>>> sup = Super()
>>> sub = Sub()
>>> sup.method1()
Super
>>> sub.method1()
Super
SubX
是LSP的上Sub.method1接受3个参数,而Super.method1发生的事实,违反了无其实不同使他们接口? – Unode 2011-05-18 16:59:55
@Unode:正确。这可以通过让子类的方法的参数全部具有默认值来解决,但是然后您得到哪些默认值是合适的。 – 2011-05-18 17:02:14
我明白了。但后来只是为了澄清。如果父方法1被定义为'Super.method1(param1 = None,param2 = None,param3 = None)',它仍然会违反LSP,如果它在子类上被定义为'Sub.method1(param1,param2,param3)'right?由于属性在一个案例中是强制性的,而不是另一个。因此,根据我的理解,在不更改子类接口的情况下,不违反LSP的唯一方法是使父类中没有默认值的参数。我是否正确或过度解释LSP? – Unode 2011-05-18 18:44:17