输出的结果为:
汪汪汪汪汪!重写父类方法的原理是,当示例调用方法时,会先在自己的类方法中查找,如果找不到,才会去父类中查找是否有相应的方法 。如果在自己的类方法中找到了需要的方法,就不会去父类中查找,也就调用不到父类的同名方法,从而实现对父类中方法的重写
调用父类方法但是有些时候,我们不得已会写一些重名的方法,比如父类和子类都会有 __init__ 构造方法 。但是我们在调用子类方法的同时,也希望调用到父类中相应的方法 。我们可以通过父类的类名直接调用:
class Father:eye_num = 2def __init__(self, name, age):self.name = nameself.age = agedef live_like_yemen(self):print('打儿子')class Son(Father):hair_color = '蓝色'def __init__(self, name, age, sex):Father.__init__(self, name, age)self.sex = sexdef live_like_yemen(self):print('打弟弟')xiaoming = Son('小明', 16, '男')xiaoming.live_like_yemen()print(xiaoming.name)输出的结果为:
打弟弟小明需要注意的是,在类中,self 永远指的是调用类的实例化对象 。
super 方法在上面的例子中,如果没有 Father.__init__(self, name, age) 这行代码,在子类中就无法调用父类的构造方法,因为子类已经重写了构造方法 。上面的方法虽然实现了预期的功能,但是并不符合开发规范 。
从子类中,调用父类中方法的关键字是 super,上述例子可修改为:
class Father:eye_num = 2def __init__(self, name, age):self.name = nameself.age = agedef live_like_yemen(self):print('打儿子')class Son(Father):hair_color = '蓝色'def __init__(self, name, age, sex):super().__init__(name, age)# 也可以写为super(Son, self).__init__(name, age)self.sex = sexdef live_like_yemen(self):print('打弟弟')xiaoming = Son('小明', 16, '男')xiaoming.live_like_yemen()print(xiaoming.name)super 方法:
- 子类如果编写了自己的构造方法,但是没有声明要调用父类的构造方法,而还需要父类的构造函数中初始化的一些属性,就会出现问题
- 如果子类和父类都有构造函数,子类的构造函数其实是对父类的构造函数的重写 。如果不显示调用父类构造函数,父类的构造函数便不会被执行
- 解决方法:直接使用超类的类名调用超类构造方法,或者使用 super 函数 super(当前类名, self).__init__()
- 子类可以重写父类中的方法
- 通过 super 关键字可以调用父类中的方法
多重继承:包含多个间接父类
class A(object): passclass B(A): passclass C(B): pass多继承:有多个直接父类class X(object): passclass Y(object): passclass Z(object): passclass M(X, Y, Z): pass大部分面向对象的编程语言(除了 C++)都只支持单继承,而不支持多继承- 多继承不仅增加了编程的复杂度,而且很容易导致一些莫名的错误 ^1
- 这样可以保证编程思路更清晰,而且可以避免很多麻烦
- 排在前面的父类中的方法会 “遮蔽 “排在后面的父类中的同名方法
class A:def method(self):print('A_method')class B:def method(self):print('B_method')class C(A, B):passc = C()c.method()输出的结果为:A_method钻石继承和 MRO我们刚刚谈到,即便不使用 super 方法,直接使用父类的类名,同样可以实现对父类方法的调用 。那为什么更推荐使用 super 方法呢?这是因为当涉及到比较复杂得多继承关系,比如钻石继承关系时,会出现间接父类会被初始化多次的情况 。
比如,我们来看下面这个钻石继承的例子,如果我们使用父类的类名调用构造方法:
class YeYe:def __init__(self):print('初始化爷爷类')class QinBa(YeYe):def __init__(self):print('进入化亲爸类')YeYe.__init__(self)print('初始化亲爸类')class GanDie(YeYe):def __init__(self):print('进入化干爹类')YeYe.__init__(self)print('初始化干爹类')class ErZi(QinBa, GanDie):def __init__(self):print('进入化儿子类')QinBa.__init__(self)GanDie.__init__(self)print('初始化儿子类')erzi = ErZi()
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- python中模块与包
- 跨平台Python异步聊天机器人框架,支持QQ、飞书、钉钉等渠道
- 4 步打包一个新的 Python 模块
- 什么是地震预警?手机如何实现地震预警功能?专家解读
- 汪圆圆|香港第一好命儿媳汪圆圆,模特嫁入百亿豪门,3年生3娃掌握继承权
- 何超云|真爱,父亲是千亿富豪,何超云未来可继承几十亿,却选择嫁给消防队长
- 成吉思汗到忽必烈怎么继承的?世界上成吉思汗的儿子忽必烈
- 孙策为什么把位置传给孙权?孙权是什么时候继承孙策的位置
- 康熙属意谁继承皇位?康熙让哪个儿子继位
- 编程|胡渊鸣:import一个“太极”库 让Python代码提速100倍!
