面向对象(三大特征、继承下的查找、super、组合)
继承
继承其实和封装差不多,就是新建的类称为是子类或派生类,多个子类继承同一个类,这个类教父类或基类
1.为什么要继承
类解决什么问题:解决的是对象与对象之间代码冗余问题
继承解决什么问题:解决的是类与类之间的代码冗余问题
2.怎样继承
新式类:继承了objcet类的所有都新式类
经典类:没有继承object类的所有的都是经典类
ps:只要在python2中才区分经典类和新式类,因为在python3中都是新式类
子类可以继承多个父类:
class Aaa: a = 111 class Bbb: b = 222 class Ccc(Aaa, Bbb): # Ccc是子集,Aaa和Bbb都是父集 c = 333 print(Ccc.b) # 222
单继承下的属性查找
单继承就是一个类只继承一个类
查找顺序:
先从对象自己的名称空间中查找,然后去产生这个对象的类中查找,最后在去继承的父类中查找,如果还找不到就报错
多继承下的属性查找
多继承就是一个类继承多个类
多继承下的属性查找分为:
1.菱形查找
就是一个子类中多条线继承同一个父集
代码会被子类从头到尾依次扫描一遍,当需要调用父类时,会允许最后一条链接父类的线
2.非菱形查找
就是一个子类中只有一条线存在一个父集
多态与多态(理论)
多态就是一种事物有多种形态,就是多个类中他们有一样的方法,它们就是一种类型的多态
如何让一个子类必须满足某一个方法:
强制Bbb中必须存在aaa的方法。
在定义父类的时候在括号内写入 metaclass=abc.ABCMeta ,这时这个父类就变成了抽象类,
只能被继承,不能被实际化,抽象类中的方法,而抽象方法不再实现具体功能,而是用来现在子类的行为
抽象类的方法上方必须添加语法糖 @abc.abstractmethod
### 这种方法python是不推荐的,python推荐的是鸭子类型
import abc # 导入函数 抽象的 class Aaa(metaclass=abc.ABCMeta): @abc.abstractmethod def aaa(self): pass class Bbb(Aaa): def aaa(self): pass pass res = Bbb()
super关键字
当一个类继承父类时,在类中需要使用父类产生的对象时,可以用super关键字代替父类名
super严格依赖继承
继承的类名.__init__(self,形参)
被替代
super(当前类名,self).__init__(形参) python2
super().__init__(形参)
当类中存在多个super关键字时,需要用mro配合使用查看super所指向的父类
特殊情况
class A: def test(self): super().test() class B: def test(self): print('from B') class C(A, B): pass c = C() print(C.mro()) # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>] c.test() # from B
组合
组合就是一个对象的某个属性的值是另一个对象
class People(): def __init__(self, name, age, gender): """这个是指名道姓的调用方法,不依赖于继承""" self.name = name self.age = age self.gender = gender """ 继承一般用在什么是什么的时候 组合一般用在什么有什么的时候 """ class Course: def __init__(self, course_name, course_price, course_period): """这个是指名道姓的调用方法,不依赖于继承""" self.course_name = course_name self.course_price = course_price self.course_period = course_period python = Course("python", 10000, '6mon') linux = Course("linux", 20000, '5mon') class Student(People): def __init__(self, name, age, gender, course=None): if course is None: course = [] """这个是指名道姓的调用方法,不依赖于继承""" super(Student, self).__init__(name, age, gender) self.courses = course def choose_course(self): pass stu = Student('kevin', '19', 'male') # print(stu.course_name) # print(stu.course_price) stu.courses.append(python) # stu.courses ====> [python对象] stu.courses.append(linux) # stu.courses ====> [python对象, linux对象] print(stu.courses)