Python基础:面向对象基础(二) 继承
子类在继承的时候,在定义类时,小括号()中为父类的名字,父类的属性、方法,会被继承给子类,Python中允许多继承。
多继承
# 父类 Master class Master(object): def __init__(self): self.kongfu = "古法煎饼果子配方" # 实例变量,属性 def make_cake(self): # 实例方法,方法 print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) def dayandai(self): print("师傅的大烟袋..") # 父类 School class School(object): def __init__(self): self.kongfu = "现代煎饼果子配方" def make_cake(self): print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) def xiaoyandai(self): print("学校的小烟袋..") # class Prentice(School, Master): # 多继承,继承了多个父类(School在前) # pass # 子类 继承Master School (多继承) class Prentice(Master, School): # 多继承,继承了多个父类(Master在前) pass damao = Prentice() print(damao.kongfu) # 执行Master的属性 如果重名取的是第一个父类的方法 damao.make_cake() # 执行Master的实例方法 # 子类的魔法属性__mro__决定了属性和方法的查找顺序 print(Prentice.__mro__) damao.dayandai() # 不重名不受影响 damao.xiaoyandai() # 多继承可以继承多个父类,也继承了所有父类的属性和方法 # 注意:如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性mro的顺序来查找) # 多个父类中,不重名的属性和方法,不会有任何影响。
重写父类方法及调用父类方法
# 继承父类 重写父类方法/调用父类方法 class Master(object): def __init__(self): self.kongfu = "古法煎饼果子配方" # 实例变量,属性 def make_cake(self): # 实例方法,方法 print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) class School(object): def __init__(self): self.kongfu = "现代煎饼果子配方" def make_cake(self): print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) class Prentice(School, Master): # 多继承,继承了多个父类 def __init__(self): self.kongfu = "猫氏煎饼果子配方" def make_cake(self): print("执行子类的__init__方法前,self.kongfu属性:%s" % self.kongfu) self.__init__() # 执行本类的__init__方法,做属性初始化 self.kongfu = "猫氏...." print("执行子类的__init__方法前,self.kongfu属性:%s" % self.kongfu) print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) # 调用父类方法格式:父类类名.父类方法(self) def make_old_cake(self): # 不推荐这样访问父类的实例属性,相当于创建了一个新的父类对象 # print("直接调用Master类的kongfu属性:%s" % Master().kongfu) # 可以通过执行Master类的__init__方法,来修改self的属性值 print("执行Master类的__init__方法前,self.kongfu属性:%s" % self.kongfu) Master.__init__(self) # 调用了父类Master的__init__方法 self.kongfu = "古法...." print("执行Master类的__init__方法后,self.kongfu属性:%s" % self.kongfu) Master.make_cake(self) # 调用父类Master的实例方法 def make_new_cake(self): # 不推荐这样访问类的实例属性,相当于创建了一个新的父类对象 # print("直接调用School类的kongfu属性:%s" % School().kongfu) # 可以通过执行School类的__init__方法,来修改self的属性值 print("执行School类的__init__方法前,self.kongfu属性:%s" % self.kongfu) School.__init__(self) # 调用了父类School的__init__方法 self.kongfu = "现代...." print("执行School类的__init__方法后,self.kongfu属性:%s" % self.kongfu) School.make_cake(self) # 调用父类School的实例方法 # 实例化对象,自动执行子类的__init__方法 damao = Prentice() damao.make_cake() # 调用子类的方法(默认重写了父类的同名方法) print("--" * 10) damao.make_old_cake() # 进入实例方法去调用父类Master的方法 print("--" * 10) damao.make_new_cake() # 进入实例方法去调用父类School的方法 print("--" * 10) damao.make_cake() # 调用本类的实例方法
通过super()调用父类方法(如果继承多个父类,有同名方法,使用super调用会把多个父类的方法都调用一遍)
class Master(object): def __init__(self): self.kongfu = "古法煎饼果子配方" # 实例变量,属性 def make_cake(self): # 实例方法,方法 print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) # 父类是 Master类 class School(Master): def __init__(self): self.kongfu = "现代煎饼果子配方" def make_cake(self): print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) super().__init__() # 执行父类的构造方法 super().make_cake() # 执行父类的实例方法 # 父类是 School 和 Master class Prentice(School, Master): # 多继承,继承了多个父类 def __init__(self): self.kongfu = "猫氏煎饼果子配方" def make_cake(self): self.__init__() # 执行本类的__init__方法,做属性初始化 self.kongfu = "猫氏...." print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) def make_all_cake(self): # 方式1. 指定执行父类的方法(代码臃肿) # School.__init__(self) # School.make_cake(self) # # Master.__init__(self) # Master.make_cake(self) # # self.__init__() # self.make_cake() # 方法2. super() 带参数版本,只支持新式类 # super(Prentice, self).__init__() # 执行父类的 __init__方法 # super(Prentice, self).make_cake() # self.make_cake() # 方法3. super()的简化版,只支持新式类 super().__init__() # 执行父类的 __init__方法 print("*" * 20) super().make_cake() # 执行父类的 实例方法 print("*" * 20) self.make_cake() # 执行本类的实例方法 damao = Prentice() print("-" * 20) damao.make_cake() print("-" * 20) damao.make_all_cake() # print(Prentice.__mro__)