一、继承的概念
Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的属性和方法
# 父类A
class A(object):
def __init__(self):
self.num = 1
def info_print(self):
print(self.num)
# 子类B
class B(A):
pass
# 创建对象,验证结论
result = B()
result.info_print() # 1
在Python中,所有类默认继承object类,object类是顶级类或基类;其他子类叫做派生类
二、单继承
- 逍遥派掌门人无崖子决定在离世之前将一身绝学传给虚竹
- 分析:徒弟是不是要继承师父的所有武功?
# 1. 师父类
class Master(object):
def __init__(self):
self.kongfu = '[北冥神功]'
def beiming(self):
print(f'虚竹运用{self.kongfu}击败敌人')
# 2. 徒弟类
class Prentice(Master):
pass #
3. 创建对象
xuzhu xuzhu = Prentice()
# 4. 对象访问实例属性
print(xuzhu.kongfu)
# 5. 对象调用实例方法
xuzhu.beiming() # 虚竹运用[北冥神功]击败敌人
三、多继承
所谓多继承意思就是一个类同时继承了多个父类
- 虚竹在继承无崖子功力之前,曾是少林寺僧人,会些许少林武功
class XiaoYao(object):
def __init__(self):
self.wugong = '[北冥神功]'
def kongfu(self):
print(f'运用{self.wugong}击败敌人')
# 少林武功
class ShaoLin(object):
def __init__(self):
self.wugong = '[波若掌]'
def kongfu(self):
print(f'运用{self.wugong}击败敌人')
class Prentice(ShaoLin, XiaoYao):
pass
xuzhu = Prentice()
print(xuzhu.wugong)
xuzhu.kongfu() # 运用[波若掌]击败敌人
注意:当一个类有多个父类的时候,默认使用第一个父类的同名属性和方法。
四、子类重写父类同名方法和属性
- 虚竹潜心修炼自创逍遥游
子类和父类具有同名属性和方法,默认使用子类的同名属性和方法。class XiaoYao(object): def __init__(self): self.wugong = '[北冥神功]' def kongfu(self): print(f'运用{self.wugong}击败敌人') # 少林武功 class ShaoLin(object): def __init__(self): self.wugong = '[波若掌]' def kongfu(self): print(f'运用{self.wugong}击败敌人') class Prentice(ShaoLin, XiaoYao): def __init__(self): self.wugong = '[逍遥游]' def kongfu(self): print(f'运用{self.wugong}击败敌人') xuzhu = Prentice() print(xuzhu.wugong) xuzhu.kongfu() # 运用[逍遥游]击败敌人 print(Prentice.__mro__) # 查看一个类继承的父类以及层级关系
五、子类调用父类的同名方法和属性
- 乔峰想要领教一下三弟虚竹的武功,于是虚竹使出了浑身解数
# 逍遥派武功 class XiaoYao(object): def __init__(self): self.wugong = '[北冥神功]' def kongfu(self): print(f'运用{self.wugong}击败敌人') # 少林武功 class ShaoLin(object): def __init__(self): self.wugong = '[波若掌]' def kongfu(self): print(f'运用{self.wugong}击败敌人') class Prentice(ShaoLin, XiaoYao): def __init__(self): self.wugong = '[逍遥游]' def kongfu(self): self.__init__() print(f'运用{self.wugong}击败敌人') def xiaoyao_kongfu(self): XiaoYao.__init__(self) XiaoYao.kongfu(self) def shaolin_kongfu(self): ShaoLin.__init__(self) ShaoLin.kongfu(self) xuzhu = Prentice() # print(xuzhu.wugong) # xuzhu.kongfu() xuzhu.xiaoyao_kongfu() xuzhu.shaolin_kongfu() xuzhu.kongfu()
六、多层继承
- 多年后虚竹想要将武功再传下去,挑选了一位徒弟
class XiaoYao(object): def __init__(self): self.wugong = '[北冥神功]' def kongfu(self): print(f'运用{self.wugong}击败敌人') class ShaoLin(object): def __init__(self): self.wugong = '[波若掌]' def kongfu(self): print(f'运用{self.wugong}击败敌人') class Prentice(ShaoLin, XiaoYao): def __init__(self): self.wugong = '[逍遥游]' def kongfu(self): self.__init__() print(f'运用{self.wugong}击败敌人') def xiaoyao_kongfu(self): XiaoYao.__init__(self) XiaoYao.kongfu(self) def shaolin_kongfu(self): ShaoLin.__init__(self) ShaoLin.kongfu(self) class TuDi(Prentice): pass tudi = TuDi() tudi.kongfu() tudi.shaolin_kongfu() tudi.xiaoyao_kongfu()
七、super()调用父类方法
# 逍遥派武功
class XiaoYao(object):
def __init__(self):
self.wugong = '[北冥神功]'
def kongfu(self):
print(f'运用{self.wugong}击败敌人')
# 少林武功
class ShaoLin(XiaoYao):
def __init__(self):
self.wugong = '[波若掌]'
def kongfu(self):
print(f'运用{self.wugong}击败敌人')
# super()
# 2.1 带参数
# super(ShaoLin,self).__init__()
# super(ShaoLin,self).kongfu()
#2.2 无参数
super().__init__()
super().kongfu()
class Prentice(ShaoLin):
def __init__(self):
self.wugong = '[逍遥游]'
def kongfu(self):
self.__init__()
print(f'运用{self.wugong}击败敌人')
def xiaoyao_kongfu(self):
XiaoYao.__init__(self)
XiaoYao.kongfu(self)
def shaolin_kongfu(self):
ShaoLin.__init__(self)
ShaoLin.kongfu(self)
# 一次性调用两个父类的方法
def two_kongfu(self):
# 方法一:如果类型修改,这里代码也要修改,而且如果代码量庞大,会很麻烦,几乎都是冗余的 代码
# XiaoYao.__init__(self)
# XiaoYao.kongfu(self)
# ShaoLin.__init__(self)
# ShaoLin.kongfu(self)
# 方法二:super()
# 2.1、super(当前类名,self).函数()
# super(Prentice,self).__init__()
# super(Prentice,self).kongfu()
# 2.2、super() 无参数
super().__init__()
super().kongfu()
xuzhu = Prentice()
xuzhu.two_kongfu()
另外,子类的对象属性不能超过其各个父类属性个数的最大值,如果不同父类有不同的属性定义,子类
需要全部继承时,需要使用args,*kwargs不定长参数使父类的属性个数不定长,此时子类继承时能
获得所有的属性。
class XiaoYao(object):
def __init__(self,*args,**kwargs):
self.wugong = '[北冥神功]'
self.music = '[达拉崩吧]'
super().__init__(*args,**kwargs)
def kongfu(self):
print(f'运用{self.wugong}击败敌人')
# 少林武功
class ShaoLin(object):
def __init__(self,*args,**kwargs):
self.wugong = '[波若掌]'
super().__init__(*args,**kwargs)
def kongfu(self):
print(f'运用{self.wugong}击败敌人')
class Prentice(ShaoLin, XiaoYao):
def __init__(self):
super().__init__()
xuzhu = Prentice()
print(xuzhu.wugong)
print(xuzhu.music)
八、私有权限
8.1 定义私有属性和私有方法
在Python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或实例方法不继承给子类。
设置私有权限的方法:在属性名和方法名 前面 加上两个下划线 __。
- 虚竹临终前,不想把自己的钱给徒弟
注意:稀有属性和私有方法只能在类里面访问和修改class XiaoYao(object): def __init__(self): self.wugong = '[北冥神功]' def kongfu(self): print(f'运用{self.wugong}击败敌人') class ShaoLin(object): def __init__(self): self.wugong = '[波若掌]' def kongfu(self): print(f'运用{self.wugong}击败敌人') class Prentice(ShaoLin, XiaoYao): def __init__(self): self.wugong = '[逍遥游]' self.__money = 200000 def kongfu(self): self.__init__() print(f'运用{self.wugong}击败敌人') def __info_print(self): print("私有方法") class TuDi(Prentice): pass tudi = TuDi() print(tudi.__money) # 报错 tudi.__info_print() # 报错
8.2 获取和修改私有属性值
class XiaoYao(object):
def __init__(self):
self.wugong = '[北冥神功]'
def kongfu(self):
print(f'运用{self.wugong}击败敌人')
class ShaoLin(object):
def __init__(self):
self.wugong = '[波若掌]'
def kongfu(self):
print(f'运用{self.wugong}击败敌人')
class Prentice(ShaoLin, XiaoYao):
def __init__(self):
self.wugong = '[逍遥游]'
self.__money = 200000
def kongfu(self):
self.__init__()
print(f'运用{self.wugong}击败敌人')
# 获取私有属性
def get_money(self):
return self.__money
# 修改私有属性
def set_money(self):
self.__money = 500
def __info_print(self):
print('私有方法')
class TuDi(Prentice):
pass
tudi = TuDi()
print(tudi.get_money())
tudi.set_money()
print(tudi.get_money())