假设我有
class Super():
def method1():
pass
class Sub(Super):
def method1(param1, param2, param3):
stuff
这是正确的吗?对method1的调用是否总是转到子类?我的计划是有 2 个子类,每个子类都使用不同的参数覆盖 method1
最佳答案
在 Python 中,方法只是附加到类的字典中的键值对。当您从基类派生类时,您实际上是在说方法名称将在第一个派生类字典中查找,然后在基类字典中查找。为了“覆盖”一个方法,您只需在派生类中重新声明该方法即可。
那么,如果你改变派生类中被覆盖方法的签名呢?如果在派生实例上调用一切正常,但如果在基实例上进行调用,则会收到错误消息,因为基类对同一方法名称使用不同的签名。
然而,在某些情况下,您希望派生类方法具有 附加 参数,并且您希望方法调用在基础上也能正常工作。这被称为“Liskov 替换原则”(或 LSP),它保证如果人们从基础实例切换到派生实例,反之亦然,他们不必修改他们的代码。要在 Python 中执行此操作,您需要使用以下技术设计基类:
class Base:
# simply allow additional args in base class
def hello(self, name, *args, **kwargs):
print("Hello", name)
class Derived(Base):
# derived class also has unused optional args so people can
# derive new class from this class as well while maintaining LSP
def hello(self, name, age=None, *args, **kwargs):
super(Derived, self).hello(name, age, *args, **kwargs)
print('Your age is ', age)
b = Base()
d = Derived()
b.hello('Alice') # works on base, without additional params
b.hello('Bob', age=24) # works on base, with additional params
d.hello('Rick') # works on derived, without additional params
d.hello('John', age=30) # works on derived, with additional params
上面将打印:
Hello Alice Hello Bob Hello Rick Your age is None Hello John Your age is 30. Play with this code
关于Python方法覆盖,签名重要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6034662/