Python父类方法重写 图片看不了?点击切换HTTP 返回上层
子类扩展了父类,子类是一种特殊的父类。大部分时候,子类总是以父类为基础,额外增加新的方法。但在一些场景中,子类需要重写父类的方法。
例如,鸟类都包含了飞翔方法,其中驼鸟是一种特殊的鸟类,因此驼鸟应该是鸟的子类,它也将从鸟类获得飞翔方法,但这个飞翔方法明显不适合驼鸟,为此,驼鸟需要重写鸟类的方法。
如下程序示范了子类重写父类的方法:
这种子类包含与父类同名的方法的现象被称为方法重写(Override),也被称为方法覆盖。可以说子类重写了父类的方法,也可以说子类覆盖了父类的方法。
别忘了,Python 类相当于类空间,因此 Python 类中的方法本质上相当于类空间内的函数。所以,即使是实例方法,Python 也允许通过类名调用。区别在于:在通过类名调用实例方法时,Python 不会为实例方法的第一个参数 self 自动绑定参数值,而是需要程序显式绑定第一个参数 self。这种机制被称为未绑定方法。
通过使用未绑定方法即可在子类中再次调用父类中被重写的方法。例如如下程序:
例如,鸟类都包含了飞翔方法,其中驼鸟是一种特殊的鸟类,因此驼鸟应该是鸟的子类,它也将从鸟类获得飞翔方法,但这个飞翔方法明显不适合驼鸟,为此,驼鸟需要重写鸟类的方法。
如下程序示范了子类重写父类的方法:
class Bird: # Bird类的fly()方法 def fly(self): print("我在天空里自由自在地飞翔...") class Ostrich(Bird): # 重写Bird类的fly()方法 def fly(self): print("我只能在地上奔跑...") # 创建Ostrich对象 os = Ostrich() # 执行Ostrich对象的fly()方法,将输出"我只能在地上奔跑..." os.fly()运行上面程序,将看到运行 os.fly() 时执行的不再是 Bird 类的 fly() 方法,而是 Ostrich 类的 fly() 方法。
这种子类包含与父类同名的方法的现象被称为方法重写(Override),也被称为方法覆盖。可以说子类重写了父类的方法,也可以说子类覆盖了父类的方法。
使用未绑定方法调用被重写的方法
如果在子类中调用重写之后的方法,Python 总是会执行子类重写的方法,不会执行父类中被重写的方法。如果需要在子类中调用父类中被重写的实例方法,那该怎么办呢?别忘了,Python 类相当于类空间,因此 Python 类中的方法本质上相当于类空间内的函数。所以,即使是实例方法,Python 也允许通过类名调用。区别在于:在通过类名调用实例方法时,Python 不会为实例方法的第一个参数 self 自动绑定参数值,而是需要程序显式绑定第一个参数 self。这种机制被称为未绑定方法。
通过使用未绑定方法即可在子类中再次调用父类中被重写的方法。例如如下程序:
class BaseClass: def foo (self): print('父类中定义的foo方法') class SubClass(BaseClass): # 重写父类的foo方法 def foo (self): print('子类重写父类中的foo方法') def bar (self): print('执行bar方法') # 直接执行foo方法,将会调用子类重写之后的foo()方法 self.foo() # 使用类名调用实例方法(未绑定方法)调用父类被重写的方法 BaseClass.foo(self) sc = SubClass() sc.bar()上面程序中 SubClass 继承了 BaseClass 类,并重写了父类的 foo() 方法。接下来程序在 SubClass 类中定义了 bar() 方法,该方法的第 11 行代码直接通过 self 调用 foo() 方法,Python 将会执行子类重写之后的 foo() 方法;第 13 行代码通过未绑定方法显式调用 BaseClass 中的 foo 实例方法,井显式为第一个参数 self 绑定参数值,这就实现了调用父类中被重写的方法。