继承
- 继承的概念
- 单继承
- 多继承
- 子类重写父类同名的属性和方法
- 子类调用父类同名的属性和方法
- 多层继承
- super
- 私有属性和方法
1. 继承的概念
继承的概念:子类 拥有 父类 的所有 方法 和 属性
优点:减少代码量
python面对对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所由属性和方法,具体如下:
class 类名(父类名):
pass
示例:
class A():
def __init__(self):
self.name = 'tom'
def run(self):
print('继承的子类可以调用我')
class B(A):
pass
test = B()
test.run()
n =test.name
print(n)
'''
继承的子类可以调用我
tom
'''
2. 单继承
- 子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次
- 开发子类 中应该根据职责,封装子类特有的属性和方法
师傅把煎饼技术传授给他最得意的弟子
class Master(object):
def __init__(self):
self.name = '古法煎饼'
def make_cake(self):
print('使用%s做煎饼'%self.name)
class Students(Master):
pass
dagu = Students()
print(dagu.name)
dagu.make_cake()
'''
古法煎饼
使用古法煎饼做煎饼
'''
3.多继承
- 子类 可以拥有 多个父类,并且具有 所有父类 的 属性 和 方法
- 例如:孩子 会继承自己 父亲 和 母亲 的 特性
class 子类名(父类名1, 父类名2...)
pass
class Master(object):
def __init__(self):
self.name = '古法煎饼'
def make_cake(self):
print('使用%s做煎饼'%self.name)
class School():
def __init__(self):
self.kongfu = '[网课煎饼配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作煎饼果子')
class Students(Master,School):
pass
dagu = Students()
print(dagu.name)
dagu.make_cake()
'''
古法煎饼
使用古法煎饼做煎饼
'''
注意:当一个类有多个父类得时候,默认使用第一个父类得同名属性和方法
4.子类重写父类同名方法和属性
当 父类 的方法实现不能满足子类需求时,可以对方法进行 重写(override)
- 如果在开发中,父类的方法实现 和 子类的方法实现,完全不同
- 就可以使用 覆盖 的方式,在子类中 重新编写 父类的方法实现
具体的实现方式,就相当于在 子类中 定义了一个 和父类同名的方法并且实现
重写之后,在运行时,只会调用 子类中重写的方法,而不再会调用父类封装的方法
class Master(object):
def __init__(self):
self.name = '古法煎饼'
def make_cake(self):
print('使用%s做煎饼'%self.name)
class School():
def __init__(self):
self.kongfu = '[网课煎饼配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作煎饼果子')
class Students(Master,School):
def __init__(self):
self.name = '独创煎饼果子'
def make_cake(self):
print(f'运用{self.name}制作煎饼果子')
dagu = Students()
print(dagu.name)
dagu.make_cake()
'''
独创煎饼果子
运用独创煎饼果子制作煎饼果子
'''
- Python 中针对类提供了一个内置属性 mro 可以查看方法搜索顺序
- MRO是method resolution order ,主要用于在多继承时判断方法、属性的调用路径
print(Students.mro()) # 返回列表形式
print(Students.__mro__) # 返回元组形式
'''
[<class '__main__.Students'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>]
(<class '__main__.Students'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
'''
5.子类调用父类得同名方法和属性
class Master(object):
def __init__(self):
self.name = '古法煎饼'
def make_cake(self):
print('使用%s做煎饼'%self.name)
class School():
def __init__(self):
self.kongfu = '[网课煎饼配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作煎饼果子')
class Students(Master,School):
def __init__(self):
self.name = '独创煎饼果子'
def make_cake(self):
self.__init__()
print(f'运用{self.name}制作煎饼果子')
def make_master_cake(self):
Master.__init__(self) # self必须写
Master.make_cake(self) # self必须写
def make_school_cake(self):
School.__init__(self) # self必须写
School.make_cake(self) # self必须写
dagu = Students()
dagu.make_master_cake() # 古法
dagu.make_school_cake() # 学校
dagu.make_cake() # 自创
'''
使用古法煎饼做煎饼
运用[网课煎饼配方]制作煎饼果子
运用独创煎饼果子制作煎饼果子
'''
TIP:
调用master和school函数时必须写上参数,并且使用 init函数对函数进行初始化
6.多层继承
class Master(object):
def __init__(self):
self.name = '古法煎饼'
def make_cake(self):
print('使用%s做煎饼'%self.name)
class School():
def __init__(self):
self.kongfu = '[网课煎饼配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作煎饼果子')
class Students(Master,School):
def __init__(self):
self.name = '独创煎饼果子'
def make_cake(self):
self.__init__()
print(f'运用{self.name}制作煎饼果子')
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(Students):
pass
xiaogu = Tusun()
xiaogu.make_school_cake()
xiaogu.make_cake()
'''
运用[网课煎饼配方]制作煎饼果子
运用独创煎饼果子制作煎饼果子
'''
7. super调用父类方法
'''
super()
'''
class Master(object):
def __init__(self):
self.name = '古法煎饼'
def make_cake(self):
print('使用%s做煎饼'%self.name)
class School(Master):
def __init__(self):
self.kongfu = '[网课煎饼配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作煎饼果子')
# super调用父类方法
super().__init__()
super().make_cake()
class Students(School):
def __init__(self):
self.name = '独创煎饼果子'
def make_cake(self):
self.__init__()
print(f'运用{self.name}制作煎饼果子')
def make_school_cake(self):
# super调用父类方法,只能调用上一层函数的方法
super().__init__()
super().make_cake()
dagu = Students()
dagu.make_school_cake()
'''
运用[网课煎饼配方]制作煎饼果子
使用古法煎饼做煎饼
'''
使用super()可以自动查找父类。调用顺序遵循——mro—类属性得顺序。比较适合单继承使用。
8. 私有属性
8.1 定义私有属性和方法
- 子类对象不能在自己的方法内部,直接访问父类的私有属性或私有方法
- 子类对象可以通过父类的公有方法间接访问到私有属性或私有方法
- 私有属性、方法是对象的隐私,不对外公开,外界以及子类都不能直接访问
- 私有属性、方法通常用于做一些内部的事情
- B 的对象不能直接访问 __num2 属性
- B 的对象不能在 demo 方法内访问 __num2 属性
- B 的对象可以在 demo 方法内,调用父类的 test 方法
- 父类的 test 方法内部,能够访问 __num2 属性和 __test 方法
__私有属性
——私有方法
'''
super()
'''
class Master(object):
def __init__(self):
self.name = '古法煎饼'
def make_cake(self):
print('使用%s做煎饼'%self.name)
class School(Master):
def __init__(self):
self.kongfu = '[网课煎饼配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作煎饼果子')
# super调用父类方法
super().__init__()
super().make_cake()
class Students(School):
def __init__(self):
self.name = '独创煎饼果子'
# 私有属性
self.__money = 200000
def __info_write(self):
print(self.name)
print(self.__money)
def make_cake(self):
self.__init__()
print(f'运用{self.name}制作煎饼果子')
def make_school_cake(self):
# super调用父类方法,只能调用上一层函数的方法
super().__init__()
super().make_cake()
class Tusun(Students):
pass
dagu = Tusun()
dagu.make_school_cake()
# print(dagu.__money) # 无法使用
# dagu.__info_write() # 报错无法使用私有属性
8.2 获取和修改私有属性值
在python中,一般定义函数名get_xx用来获取私有属性,定义set_xx用来修改私有属性。
'''
get—_xxxx()
私有属性获取
'''
class Master(object):
def __init__(self):
self.name = '古法煎饼'
def make_cake(self):
print('使用%s做煎饼'%self.name)
class School(Master):
def __init__(self):
self.kongfu = '[网课煎饼配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作煎饼果子')
# super调用父类方法
super().__init__()
super().make_cake()
class Students(School):
def __init__(self):
self.name = '独创煎饼果子'
# 私有属性
self.__money = 200000
# 获取私有属性
def get_money(self):
return self.__money
# 修改私有属性函数
def set_money(self):
self.__money = 15000
def make_cake(self):
self.__init__()
print(f'运用{self.name}制作煎饼果子')
def make_school_cake(self):
# super调用父类方法,只能调用上一层函数的方法
super().__init__()
super().make_cake()
class Tusun(Students):
pass
dagu = Tusun()
dagu.make_school_cake()
print(dagu.get_money())
dagu.set_money()
print(dagu.get_money())
'''
运用[网课煎饼配方]制作煎饼果子
使用古法煎饼做煎饼
200000
15000
'''