2011-05-17 58 views
26

可以说我有Python方法重写,签名问题?

class Super(): 
    def method1(): 
    pass 

class Sub(Super): 
    def method1(param1, param2, param3): 
     stuff 

这是正确的吗?将调用method1总是去到子类?我的计划是有2个子类,每个子类都使用不同的参数覆盖method1

回答

1

在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() 
25

Python会允许这样做,但如果method1()旨在从外部代码执行,那么你可能要重新考虑这一点,因为它违反了LSP等都不会始终正常工作。

+0

是LSP的上Sub.method1接受3个参数,而Super.method1发生的事实,违反了无其实不同使他们接口? – Unode 2011-05-18 16:59:55

+1

@Unode:正确。这可以通过让子类的方法的参数全部具有默认值来解决,但是然后您得到哪些默认值是合适的。 – 2011-05-18 17:02:14

+2

我明白了。但后来只是为了澄清。如果父方法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

-2

是的。调用“method1”将始终转到子类。 Python中的方法签名只包含名称而不包含参数列表。

+2

错误的答案。方法签名总是很重要,因为没有函数重载,因为它发生在C/C++中。 – 2011-05-17 17:33:52

+0

我的意思是,Python不考虑参数列表来决定调用哪种方法,但是我认为从_that_角度看它是正确的! – Elektito 2011-05-17 17:38:08

1

你可以做这样的事情,如果它是确定使用默认参数:

>>> 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