面向对象-继承
1.体验继承
python面向对象的继承指多个类之间的从属关系,即子类默认及继承父类的所有属性和方法,具体如下:
#父类
classA(object):def __init__(self):
self.num= 1
definfo_print(self):print(self.num)#子类
classB(A):passredult=B()
redult.info_print()'''输出:
1'''
在python中,所有类默认继承object类,object类是顶级类或基类,其他字类叫派生类
2.单继承
故事主线:一个煎饼果子老师傅,在煎饼果子界摸爬滚打多年,研发了一套精湛的煎饼果子技术。师傅要把这套技术传授给徒弟。
分析:要有两个类(师傅类、徒弟类),徒弟类继承师傅类
classMaster(object):def __init__(self):
self.mifang= '独门绝技'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classPrentice(Master):passtuer=Prentice()
tuer.make_cake()'''输出:
使用独门绝技制作煎饼果子'''
3.多继承
故事推进:tuer继承师傅的独门绝技后,还想去学校学习更多的技术
多继承:所谓多继承就是一个类同时继承多个父类
classMaster(object):def __init__(self):
self.mifang= '独门绝技'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classSchool(object):def __init__(self):
self.mifang= '新式秘方'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classPrentice(Master,School):passtuer=Prentice()
tuer.make_cake()'''输出:
使用独门绝技制作煎饼果子'''
结论:如果一个类同时继承多个父类,优先继承第一个父类的同名属性和方法
4.子类重写父类同名属性和方法
故事:徒弟掌握师傅和学校的技术后,自己潜心研究出了自己的独门秘方
classMaster(object):def __init__(self):
self.mifang= '独门绝技'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classSchool(object):def __init__(self):
self.mifang= '新式秘方'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classPrentice(Master,School):def __init__(self):
self.mifang= '自创秘方'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')
tuer=Prentice()
tuer.make_cake()'''输出:
使用自创秘方制作煎饼果子'''
结论:如果子类和父类拥有同名方法和属性,子类创建对象时调用属性和方法,调用到的是子类里面的同名属性和方法
5.拓展:__mro__ 子类继承的父类以及继承顺序
classMaster(object):def __init__(self):
self.mifang= '独门绝技'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classSchool(object):def __init__(self):
self.mifang= '新式秘方'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classPrentice(Master,School):def __init__(self):
self.mifang= '自创秘方'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')
tuer=Prentice()
tuer.make_cake()print(Prentice.__mro__)'''输出:
使用自创秘方制作煎饼果子
使用自创秘方制作煎饼果子
(, , , )'''
6.子类调用父类的同名属性和方法
classMaster(object):def __init__(self):
self.mifang= '独门绝技'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classSchool(object):def __init__(self):
self.mifang= '新式秘方'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classPrentice(Master,School):def __init__(self):
self.mifang= '自创秘方'
defmake_cake(self):#再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
self.__init__()print(f'使用{self.mifang}制作煎饼果子')#子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
defMaster_make_cake(self):#再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
Master.__init__(self)
Master.make_cake(self)defSchool_make_cake(self):
School.__init__(self)
School.make_cake(self)
tuer=Prentice()
tuer.make_cake()
tuer.Master_make_cake()
tuer.School_make_cake()'''输出:
使用自创秘方制作煎饼果子
使用独门绝技制作煎饼果子
使用新式秘方制作煎饼果子'''
7.多层继承
classMaster(object):def __init__(self):
self.mifang= '独门绝技'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classSchool(object):def __init__(self):
self.mifang= '新式秘方'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classPrentice(Master,School):def __init__(self):
self.mifang= '自创秘方'
defmake_cake(self):#再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
self.__init__()print(f'使用{self.mifang}制作煎饼果子')#子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
defMaster_make_cake(self):#再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
Master.__init__(self)
Master.make_cake(self)defSchool_make_cake(self):
School.__init__(self)
School.make_cake(self)classTusun(Prentice):passtuer=Tusun()
tuer.make_cake()
tuer.Master_make_cake()
tuer.School_make_cake()'''输出:
使用自创秘方制作煎饼果子
使用独门绝技制作煎饼果子
使用新式秘方制作煎饼果子'''
8.super()调用父类方法
带参数写法
super(当前类名,self).函数()
classMaster(object):def __init__(self):
self.mifang= '独门绝技'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classSchool(Master):def __init__(self):
self.mifang= '新式秘方'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')#在这里调用super方法, 才能调用Master父类里的方法和属性
defmake_cake(self):
super(School, self).__init__()
super(School, self).make_cake()classPrentice(School):def __init__(self):
self.mifang= '自创秘方'
defmake_cake(self):#再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
self.__init__()print(f'使用{self.mifang}制作煎饼果子')#子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
defMaster_make_cake(self):#再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
Master.__init__(self)
Master.make_cake(self)defSchool_make_cake(self):
School.__init__(self)
School.make_cake(self)defmake_waht_cake(self):
super(Prentice, self).__init__()
super(Prentice, self).make_cake()
tuer=Prentice()
tuer.make_waht_cake()
tuer.make_cake()'''输出:
使用独门绝技制作煎饼果子
使用自创秘方制作煎饼果子'''
无参数写法
classMaster(object):def __init__(self):
self.mifang= '独门绝技'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classSchool(Master):def __init__(self):
self.mifang= '新式秘方'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')#在这里调用super方法, 才能调用Master父类里的方法和属性
defmake_cake(self):
super().__init__()
super().make_cake()classPrentice(School):def __init__(self):
self.mifang= '自创秘方'
defmake_cake(self):#再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
self.__init__()print(f'使用{self.mifang}制作煎饼果子')#子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
defMaster_make_cake(self):#再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
Master.__init__(self)
Master.make_cake(self)defSchool_make_cake(self):
School.__init__(self)
School.make_cake(self)defmake_waht_cake(self):
super().__init__()
super().make_cake()
tuer=Prentice()
tuer.make_waht_cake()
tuer.make_cake()'''输出:
使用独门绝技制作煎饼果子
使用自创秘方制作煎饼果子'''
注意:使用super()可以自动查找父类。调用顺序遵循__mro__类属性的顺序。比较适合单继承使用。
9.私有权限
9.1定义私有属性和方法
在python中,可以为实例属性和方法设置私有权限,即设置某个实例属性和方法不继承给子类。
设置私有权限的方法:在属性名和方法名前面加两个_
classMaster(object):def __init__(self):
self.mifang= '独门绝技'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classSchool(object):def __init__(self):
self.mifang= '新式秘方'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classPrentice(Master,School):def __init__(self):
self.mifang= '自创秘方'self.__caichan = '2个亿'
defmake_cake(self):#再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
self.__init__()print(f'使用{self.mifang}制作煎饼果子')def __caichan(self):print('这是私有方法')#子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
defMaster_make_cake(self):#再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
Master.__init__(self)
Master.make_cake(self)defSchool_make_cake(self):
School.__init__(self)
School.make_cake(self)classTusun(Prentice):passtuer=Tusun()#print(tuer.caichan)#print(tuer.__caichan)#tuer.caichan()#tuer.__caichan()
四个调用都会报错,因为父类不能将私有属性和方法继承给子类
9.2获取和修改私有属性值
在python中,一般定义函数名get_xx用来获取私有属性,定义set_xx用来修改私有属性值
classMaster(object):def __init__(self):
self.mifang= '独门绝技'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classSchool(object):def __init__(self):
self.mifang= '新式秘方'
defmake_cake(self):print(f'使用{self.mifang}制作煎饼果子')classPrentice(Master,School):def __init__(self):
self.mifang= '自创秘方'self.__caichan = 200000
def __caichan(self):print('这是私有方法')#获取私有属性
defget_caichan(self):return self.__caichan
#修改私有属性
defset_caichan(self):
self.__caichan = 50000
defmake_cake(self):#再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
self.__init__()print(f'使用{self.mifang}制作煎饼果子')#子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
defMaster_make_cake(self):#再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
Master.__init__(self)
Master.make_cake(self)defSchool_make_cake(self):
School.__init__(self)
School.make_cake(self)classTusun(Prentice):passtuer=Tusun()print(tuer.get_caichan())
tuer.set_caichan()print(tuer.get_caichan())'''输出:
200000
50000'''
获取和修改私有属性不一定是get_xx和set_xx,这只是工作习惯
总结
继承的特点
子类默认拥有父类的所有属性和方法
子类重写分类同名属性和方法
子类调用父类同名属性和方法
super()快速调用父类方法
私有权限
不能继承给子类的属性和方法需要添加私有权限
语法:
class 类名()
#私有属性
__属性名 = 值
#私有方法
def __函数名(self):
代码