让我说我有
class Super():
def method1():
pass
class Sub(Super):
def method1(param1, param2, param3):
stuff
这是对的吗?对method1的调用总是会转到子类吗?我的计划是让2个子类重写方法1,使用不同的参数
答案 0 :(得分:33)
Python会允许这样做,但如果method1()
打算从外部代码执行,那么您可能需要重新考虑这一点,因为它违反了LSP,因此无法始终正常运行。
答案 1 :(得分:6)
Python允许使用具有不同签名的“覆盖”方法,但是即使它们的签名不同(即,没有方法重载),也不能在同一类中拥有两个具有相同名称的方法。在覆盖方法的情况下,如果调用的方法为该对象定义的参数数量错误,则会出现错误。记住,Python的方法只是字典中附加到对象上的键-值对,“覆盖”等于简单地替换最初从基类字典复制的相同键的字典中的值。
在许多情况下,您希望派生类方法比基本类具有 additional 参数。要在Python中同时保留LSP,可以使用以下技术:
visit_test
以上将打印:
class Base:
def hello(self, name, *kargs, **kwargs):
print("Hello", name)
class Derived(Base):
def hello(self, name, age=None, *kargs, **kwargs):
super(Derived, self).hello(name, age, *kargs, **kwargs)
print('Your age is ', age)
b = Base()
d = Derived()
b.hello('Alice')
b.hello('Bob', age=24)
d.hello('Rick')
d.hello('John', age=30)
答案 2 :(得分: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()
答案 3 :(得分:1)
它会起作用:
>>> 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。
答案 4 :(得分: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
答案 5 :(得分:-2)
是。对“method1”的调用将始终转到子类。 Python中的方法签名只包含名称而不是参数列表。