可以說我有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