目录:
- 子类调用方法时的寻找机制
- 子类调用父类方法的两种方式
- 使用super的注意事项
本文中写的方法,即python中的函数
1、子类调用方法时的寻找机制
python支持多继承,在继承时遵循“先来后到”原则 即区分继承的父类顺序,以左边的父类为先
子类对象调用方法时,寻找顺序为==》 先子类,后父类 在父类中寻找方法时,寻找顺序为从左到右,如 class
C(A,B),会先在A类中寻找,后在B类中寻找
class A:
def fun(self):
print('我是父类A中的fun方法')
def say(self,name):
print('你好,我是父类A类中的say方法,我是:',name)
class B:
def fun(self):
print('我是父类B中的fun方法')
def say(self,name):
print('你好,我是父类B类的say方法,我是:',name)
# A为继承的第一个父类,B为第二个父类
class C(A, B):
def say(self):
print('你好,我是子类C中的say方法')
c = C()
'''
子类对象调用方法时,寻找顺序为==》 先子类,后父类
在父类中寻找方法时,寻找顺序为从左到右,即先在A类中寻找,后在B类中寻找
'''
c.say() # 子类中有say()方法,优先调用子类中的方法
c.fun() # 子类中没有fun()方法,会在父类中寻找,A类在继承时的第一个类,故会调用A类中的fun()
# 打印结果
你好,我是子类C中的say方法
我是父类A中的fun方法
2、子类调用父类方法的两种方式
- 未绑定方法
- 绑定方法(推荐使用)
未绑定方法,即使用 类名.方法名(self,自定义参数)
未绑定方法即不会将对象本身自动与self参数捆绑起来
以上文中的A,B,C三个类为例,在子类中使用未绑定方法调用父类中的方法,改写子类为:
class C(A, B):
def say(self,name):
# print('你好,我是子类C中的say方法')
A.say(self,name)
c = C()
c.say('张三')
# 打印结果
你好,我是父类A类的say方法,我是:张三
绑定方法,即使用super()调用父类中的方法,该方法会自动将对象本身与self捆绑起来
使用super()分为两种方法
- super(子类名,参数).父类方法名()
- super().父类方法名
即可以这样改写上面的未绑定方法调用方式
class C(A, B):
def say(self,name):
# print('你好,我是子类C中的say方法')
# A.say(self,name)
# 下面的两种super方法的效果相同
# super(C,self).say(name)
super().say(name)
3、使用super的注意事项
当多个父类拥有同名的方法时,super会找到继承的第一个类的该方法,调用其他类的该方法,需要使用未绑定方法调用
如上面的A,B两个父类均拥有 fun() 与 say() , 子类中使用super().fun() , super().say() 指挥调用A类中的 fun() ,say() ,因为多继承时A类写在了最左边
python要求:在子类中重写父类的构造方法(__init__方法)时,必须调用父类的构造方法
再举一个例子
class Employee:
def __init__(self, salary):
self.salary = salary
def work(self):
print('普通员工正在写代码,工资是:{}'.format(self.salary))
def fun(self):
print('这是Employee类的fun()函数,用于测试多继承时的super的使用')
class Customer:
def __init__(self, favorite, address):
self.favorite = favorite
self.address = address
def info(self):
print('我是一名顾客,我的爱好是:{},地址是:{}'.format(self.favorite, self.address))
def fun(self):
print('这是Customer类的fun()函数,用于测试多继承时的super的使用')
# 多继承,Employee是一个继承的类,Customer是第二个继承的类
class Manager(Employee, Customer):
'''
python要求:在子类中重写父类的构造方法时,必须调用父类的构造方法
当多个父类拥有同名的方法时,super会找到继承的第一个类的该方法,调用其他类的该方法,需要显式的调用
'''
def __init__(self, salary, favorite, address):
# 因为先继承的Employee类,故super只能调用Employee类的构造方法
super().__init__(salary)
# super().__init__(favorite,address) 使用该方法需要将Customer类做为第一个继承的类
# super()只能用于调用第一个父类的构造方法,调用其他父类构造方法只能使用未绑定方法
Customer.__init__(self, favorite, address)
def say(self):
# 继承的多个父类中不存在同名方法时,可以使用super直接调用多个父类中的所有方法
super().info() # 继承的第一个类的方法
super().work() # 继承的第二个类的方法
def newFun(self):
# 继承的多个类拥有同名方法时,super只能调用继承的第一个类的同名方法
# super().fun() # 继承的第一个类的方法
Customer.fun(self) # 继承的第二个类的方法
man = Manager(8000, '赚钱', '学子街8号')
man.say()
# 我是一名顾客,我的爱好是:赚钱,地址是:学子街8号
# 普通员工正在写代码,工资是:8000
man.newFun()
# 这是Employee类的fun()函数,用于测试多继承时的super的使用
'''
当多个父类拥有同名的方法时,super会找到继承的第一个类的该方法
调用其他类的该方法,需要显式的调用(即使用未绑定方法)
若想在newFun()中调用继承的第二个类Customer的fun(),只能使用未绑定绑定方法调用
'''