荐 python面向对象三大特性之继承
一、什么是继承?
继承
是一种类间关系, 描述一个类从另一个类获取成员信息的类间关系。
如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”。
继承必定发生在两个类之间, 参与继承关系的双方成为是父类
和子类
。
父类提供成员信息, 子类获取成员信息。
继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码。在令子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类不同的功能。另外,还可以为子类追加新的属性和方法。
二、继承定义格式
定义格式:
calss 类名(父类名):
pass
继承父类的成员:包括变量和方法
注:
子类可以添加父类没有的成员
父类私有成员不可被继承
那么接下来用一个例子来看一下继承:
class Father:
def __init__(self):
self.name = None
self.place = None
self.__id_card = None # 对成员变量进行私有设置:self.__变量名 = 值
def hello(self):
print("hello,武汉加油,我是%s" % self.name)
# 子类
class Son(Father):
def sing(self): # # 为子类追加新的方法
print("会唱歌")
son1 = Son()
son1.name = "小明" # 子类拥有父类的name属性
son1.hello() # 子类调用父类方法
son1.sing() # 子类调用自己的方法
#son1.__id_card # AttributeError: 'Son' object has no attribute '__id_card'
# 会报错,因为父类私有成员不可被继承
程序运行结果:
三、查看继承关系
类名.__mro__可以查看继承关系
如以上示例代码最后加上一行:print(Son.mro)
打印结果:
再写个简单示例说明一下:
ass Father(object):
pass
class Son(Father):
pass
class Sun(Son):
pass
print(Sun.__mro__)
sun1 = Sun()
执行结果:
一句话,左边的继承右边的,即Sun —>Son ----->Father---->object
越往右资格越老。所以,在python3 中 object类是所有类的父类。
四、继承重写
程序实例:
lass Father:
def play(self):
print("钓鱼")
class Son(Father):
def play(self): # 重写 (覆盖)
print("打游戏")
son1 = Son()
son1.play()
print(son1)
执行结果:
那么,如何在子类里调用父类的方法呢?接着以上程序往下看:
class Father:
def play(self):
print("钓鱼")
class Son(Father):
def play(self): # 重写 (覆盖)
print("打游戏")
# 调用格式一:
# 父类名.方法名(对象)
Father.play(self)
# 调用格式二:
# super(子类名,对象).方法名()
super(Son,self).play()
# 调用格式三: 常用这个
# super().方法名()
super().play()
son1 = Son()
son1.play()
执行结果:
五、多继承
多继承也好理解,类似于一个女儿继承了妈妈的美丽和父亲的聪明,即一个子类继承了两个或以上父类的成员就叫多继承。
程序示例:
class Father1:
def sing(self):
print("唱歌唱得好听")
class Father2:
def dance(self):
print("跳舞跳得好")
class Son(Father2,Father1):
pass
son1 = Son()
son1.sing()# 子类对象可以调用两个父类的成员(成员变量和成员方法)
son1.dance()
执行结果:
多继承⽤起来简单. 也很好理解. 但是多继承中, 存在着这样⼀个问题. 当两个⽗类中出现了重名⽅法的时候. 这时该怎么办呢? 这时就涉及到如何查找⽗类⽅法的这么⼀个问题.即MRO(method resolution order) 问题. 在python中这是⼀个很复杂的问题. 因为在不同的python版本中使⽤的是不同的算法来完成MRO的.
这里需要补充一下python中类的种类:
在python2x版本中存在两种类.:
⼀个叫经典类. 在python2.2之前. ⼀直使⽤的是经典类. 经典类在基类的根如果什么都不写.
⼀个叫新式类. 在python2.2之后出现了新式类. 新式类的特点是基类的根是object类。
python3x版本中只有一种类:
python3中使⽤的都是新式类. 如果基类谁都不继承. 那这个类会默认继承 object
我们使用的python3没必要研究python2了(python2今年即2020年就不维护了),MRO啥的在这里先不谈,我们现在的目标是知道怎么用的就行了,回归正题,当遇到两个⽗类中出现了重名⽅法的时候.,记住子类继承的方法是排在最前面的那个父类的方法
,下面看一下程序示例:
class Father1:
def sing(self):
print("唱歌唱得好听")
def play(self):
print("钓钓鱼")
class Father2:
def dance(self):
print("跳舞跳得好")
def play(self):
print("打打球")
# 多个父类成员冲突的情况
class Son(Father2,Father1):# Father2在前,则父类成员冲突时会优先继承Father2的play方法
pass
son1 = Son()
son1.play()# 打打球
print(Son.__mro__)
执行结果:
那么,只能根据位置指定继承方法吗?有没有一种方法可以指定继承自哪个父类而不受继承的父类参数位置影响?当然可以,下面尝试给出以下代码:
class Father1:
def sing(self):
print("唱歌唱得好听")
def play(self):
print("钓钓鱼")
class Father2:
def dance(self):
print("跳舞跳得好")
def play(self):
print("打打球")
# 多个父类成员冲突的情况
class Son(Father2,Father1):
def play(self):
Father1.play(self)
son1 = Son()
# son1.
son1.play()
print(Son.__mro__)
执行结果:
可以看出,以上代码只是在子类中重新定义了该方法并在该方法中调用需要指定的父类方法。
本文地址:https://blog.csdn.net/weixin_44327634/article/details/107292733
上一篇: RabbitMQ的下载、安装