重写

重写

子类重写父类同名方法和属性

class Master(object):
	def __init__(self):
		self.kongfu = '[古法煎饼果子配方]'

	def make_cake(self):
		print(f'运用{self.kongfu}制作煎饼果子')

class School(object):
	def __init__(self):
		self.kongfu = '[黑马煎饼果子配方]'

	def make_cake(self):
		print(f'运用{self.kongfu}制作煎饼果子')

class Prentice(School, Master):
	def __init__(self):
		self.kongfu = '[独创煎饼果子配方]'

	def make_cake(self):
		print(f'运用{self.kongfu}制作煎饼果子')
		

daqiu = Prentice()
print(daqiu.kongfu) # 独创功夫
daqiu.make_cake() # 独创
class Master(object):
	def __init__(self):
		self.kongfu = '[古法煎饼果子配方]'

	def make_cake(self):
		print(f'运用{self.kongfu}制作煎饼果子')

class Prentice(Master):
	def __init__(self):
		self.kongfu = '[独创煎饼果子配方]'

	def make_cake(self):
		print(f'运用{self.kongfu}制作煎饼果子')
		

daqiu = Prentice()
print(daqiu.kongfu) # 独创功夫
daqiu.make_cake() # 独创

print(Prentice.__mro__) # (<class '__main__.Prentice'>, <class '__main__.Master'>, <class 'object'>)

子类调用父类的同名方法和属性

class Master(object):
	def __init__(self):
		self.kongfu = '[古法煎饼果子配方]'

	def make_cake(self):
		print(f'运用{self.kongfu}制作煎饼果子')

class School(object):
	def __init__(self):
		self.kongfu = '[黑马煎饼果子配方]'

	def make_cake(self):
		print(f'运用{self.kongfu}制作煎饼果子')

class Prentice(School, Master):
	def __init__(self):
		self.kongfu = '[独创煎饼果子配方]'

	def make_cake(self):
		# 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
		self.__init__()
		print(f'运用{self.kongfu}制作煎饼果子')

	# 如果父类方法,但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化,因为父类的属性在__init__()当中
	def make_master_cake(self):
		Master.__init__(self)
		Master.make_cake(self)

	def make_school_cake(self):
		School.__init__(self)
		School.make_cake(self)
		

daqiu = Prentice()
print(daqiu.kongfu) # 独创功夫
daqiu.make_cake() # 独创

多层继承

class Master(object):
	def __init__(self):
		self.kongfu = '[古法煎饼果子配方]'

	def make_cake(self):
		print(f'运用{self.kongfu}制作煎饼果子')

class School(object):
	def __init__(self):
		self.kongfu = '[黑马煎饼果子配方]'

	def make_cake(self):
		print(f'运用{self.kongfu}制作煎饼果子')

class Prentice(School, Master):
	def __init__(self):
		self.kongfu = '[独创煎饼果子配方]'

	def make_cake(self):
		# 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
		self.__init__()
		print(f'运用{self.kongfu}制作煎饼果子')

	# 如果父类方法,但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化,因为父类的属性在__init__()当中
	def make_master_cake(self):
		Master.__init__(self)
		Master.make_cake(self)

	def make_school_cake(self):
		School.__init__(self)
		School.make_cake(self)

class Tusun(Prentice):
	pass

xiaoqu = Tusun()
xiaoqu.make_cake()
xiaoqu.make_master_cake()
xiaoqu.make_school_cake()

super()调用父类方法

分为有参数调用和无参数调用,推荐无参数调用

class Master(object):
	def __init__(self):
		self.kongfu = '[古法煎饼果子配方]'

	def make_cake(self):
		print(f'运用{self.kongfu}制作煎饼果子')

class School(Master):
	def __init__(self):
		self.kongfu = '[黑马煎饼果子配方]'

	def make_cake(self):
		print(f'运用{self.kongfu}制作煎饼果子')
		
		# 方法1, 如果要调用Master父类的方法
		# super(School, self).__init__()
		# super(School, self).make_cake()

		# 方法2,如果要调用Master父类的方法
		super().__init__()
		super().make_cake()

class Prentice(School):
	def __init__(self):
		self.kongfu = '[独创煎饼果子配方]'

	def make_cake(self):
		# 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
		self.__init__()
		print(f'运用{self.kongfu}制作煎饼果子')

	# 如果父类方法,但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化,因为父类的属性在__init__()当中
	def make_master_cake(self):
		Master.__init__(self)
		Master.make_cake(self)

	def make_school_cake(self):
		School.__init__(self)
		School.make_cake(self)

	# 一次性调用父类School Master的方法
	def make_old_cake(self):
		# 方法1:如果定义的类名修改,这里也要修改;代码量庞大,冗余
		# School.__init__(self)
		# School.make_cake(self)
		# Master.__init__(self)
		# Master.make_cake(self)
		# 方法二:super()
		# 方法2.1 super(当前类名,self).函数()
		# super(Prentice, self).__init__()
		# super(Prentice, self).make_cake()
		
		# 方法2.2 super().函数()
		super().__init__()
		super().make_cake()

daqiu = Prentice()
daqiu.make_old_cake()

注意:使用super()可以自动查找父类。调用顺序遵循__mro__ 类属性的顺序。比较适合单继承使用