day33
一、单继承下的属性查找
1 class Foo: 2 def f1(self): 3 print("Foo.f1") 4 5 def f2(self): 6 print("Foo.f2") 7 self.f1() # self => obj 8 9 10 class Bar(Foo): 11 def f1(self): 12 print("Bar.f1") 13 14 15 obj = Bar() # 从类Bar中创建对象obj 16 obj.f2() # Foo.f2 Bar.f1 17 # 对象obj调用f2功能,先在自己的类中找功能f2,没找到时,去类Bar的父类中找,找到f2功能调用,f2功能中又有self.f1()功能 18 # 注意,此时的self就是对象obj,当对象obj调用f1功能时,先到自己的类中查找,找到后直接调用 19 20 class Foo: 21 def __f1(self): # _Foo__f1() 22 print("Foo.f1") 23 24 def f2(self): 25 print("Foo.f2") 26 self.__f1() # self._Foo__f1() 27 28 29 class Bar(Foo): 30 def __f1(self): # _Bar__f1() 31 print("Bar.f1") 32 33 34 obj = Bar() # 从类Bar中创建对象obj 35 obj.f2() # Foo.f2 Foo.f1 36 # 对象obj调用f2功能,先在自己的类中找功能f2,没找到时,去类Bar的父类中找,找到f2功能调用,f2功能中又有self.__f1()功能 37 # 注意:类中的隐藏函数在定义阶段就发生了变形,因此当功能运行到self.__f1()时,此时的self.__f1()其实已经变形为self._Foo__f1() 38 # 所以此时的obj调用的就是Foo类中的__f1()功能
二、多继承下的属性查找
菱形继承:
非菱形继承:
1、新式类:广度优先查找
2、经典类:深度优先查找
提示:Python2中存在经典类,Python3中全是新式类
1 class G: 2 def test(self): 3 print('from G') 4 5 6 class E(G): 7 # def test(self): 8 # print('from E') 9 pass 10 11 12 class D(G): 13 # def test(self): 14 # print('from D') 15 pass 16 17 18 class B(E): 19 # def test(self): 20 # print('from B') 21 pass 22 23 24 class F(G): 25 # def test(self): 26 # print('from F') 27 28 pass 29 30 31 class C(F): 32 # def test(self): 33 # print('from C') 34 pass 35 36 37 class A(B, C, D): 38 # def test(self): 39 # print('from A') 40 pass 41 42 43 f1 = A() 44 # f1.test() 45 print(A.__mro__) # 只有新式才有这个属性可以查看线性列表,经典类没有这个属性 46 47 #新式类继承顺序:A->B->E->C->F->D->G 48 #经典类继承顺序:A->B->E->G->C->F->D 49 #python3中统一都是新式类 50 #pyhon2中才分新式类与经典类
三、super继承与mro的使用
super继承:
1 class People(): 2 school = 'sh' 3 4 def __init__(self, name, age, course=None): 5 self.name = name 6 self.age = age 7 8 9 class Student(People): 10 11 def __init__(self, name, age, course): 12 # People.__init__(self, name, age) 13 # super(Student, self).__init__(name, age) # python2 14 super().__init__(name, age) # python3 15 16 self.course = course 17 18 def choose(self): 19 pass 20 21 22 class Teacher(People): 23 24 def __init__(self, name, age, level): 25 # People.__init__(self, name, age) 26 super().__init__(name, age) # python3 27 self.level = level 28 29 30 obj = Student('egon',19, 'python') 31 print(obj.name) 32 print(obj.age)
super与mro的配合使用案例
1 class A: 2 def test(self): 3 print('A---->test') 4 super().aaa() 5 class B: 6 def test(self): 7 print('B---->test') 8 9 def aaa(self): 10 print('B---->aaa') 11 12 class C(A,B): 13 def aaa(self): 14 print('C----->aaa') 15 16 c = C() 17 c.test() 18 # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>] 19 print(C.mro()) 20 21 a= A() 22 # a.test() 23 print(A.mro())
四、多态与多态性
多态:一种事物的多种状态
1、水:固态水(冰), 液态水,气态水(水蒸气)
2、动物:人,猪,狗
继承:解决类与类之间的代码冗余问题
多态类中继承:不是让子类遗传父类的属性和方法, 是用来给子类定制标准的
1 import abc # abstract => 抽象 2 3 # 该类已经为抽象类了 4 class Animal(metaclass=abc.ABCMeta): 5 6 @abc.abstractmethod 7 def speak(self): 8 pass 9 10 # @abc.abstractmethod 11 def run(self): 12 pass 13 14 15 16 class People(Animal): 17 def speak(self): 18 pass 19 # def jiao(self): 20 # pass 21 pass 22 23 24 class Dog(Animal): 25 def speak(self): 26 pass 27 28 29 class Pig(Animal): 30 def speak(self): 31 pass 32 pass 33 34 obj1 = People() 35 obj2 = Dog() 36 obj3 = Pig() 37 38 obj1.speak() 39 obj2.speak() 40 obj3.speak() 41 42 import abc # abstract => 抽象 43 44 # 该类已经为抽象类了
多态带来的特性:在不用考虑对象数据类型的情况下,直接调用对象的方法
1 class People(): 2 def speak(self): 3 pass 4 # def jiao(self): 5 # pass 6 pass 7 8 class Dog(): 9 def speak(self): 10 pass 11 12 class Pig(): 13 def speak(self): 14 pass 15 pass 16 17 obj1 = People() 18 obj2 = Dog() 19 obj3 = Pig() 20 21 # obj1.speak() 22 # obj2.speak() 23 # obj3.speak() 24 25 def animal(animal): 26 return animal.speak() 27 # 28 animal(obj1) 29 30 # len() 31 # print("abc".__len__()) 32 # print([1,2,3].__len__()) 33 # print({'k':11}.__len__()) 34 35 len('abc') 36 def len(item): 37 return item.__len__() 38 39 class Process(): 40 def read(self): 41 pass 42 43 def write(self): 44 pass 45 46 class Thead(): 47 def read(self): 48 pass 49 50 def write(self): 51 pass
五、组合
组合:一个对象拥有一个属性,该属性是另一个对象
解决类与类之间的代码冗余问题:
1、继承:满足什么是什么的关系
2、组合:满足什么有什么的关系
1 # 例一 2 class Foo: 3 x = 1 4 def __init__(self, m): 5 self.m = m 6 7 def func1(self): 8 return self.m 9 10 class Bar(): 11 y = 2 12 def __init__(self, n): 13 self.n = n 14 15 def func2(self): 16 return self.n 17 18 obj1 = Foo(10) 19 obj2 = Bar(20) 20 21 # int() 22 obj1.z = obj2 23 print(obj1.z.n) 24 25 # 例二 26 class People(): 27 school = 'sh' 28 29 def __init__(self, name, age, gender): 30 self.name = name 31 self.age = age 32 self.gender = gender 33 34 class Course(): 35 def __init__(self, course_name, course_period, course_price): 36 self.course_name = course_name 37 self.course_period = course_period 38 self.course_price = course_price 39 40 class Student(People,): 41 42 def __init__(self, name, age, gender, course=None): 43 if course is None: 44 course = [] 45 self.courses = course 46 47 super().__init__(name, age, gender) 48 49 def choose_course(self, course): 50 self.courses.append(course) 51 print("%s 选课 成功 %s" % (self.name, self.courses)) 52 53 class Teacher(People): 54 55 def __init__(self, name, age, gender, lever): 56 self.lever = lever 57 super().__init__(name, age, gender) 58 59 def score(self, stu_obj, num): 60 stu_obj.num = num 61 print("%s老师给%s学生打了%s分" % (self.name, stu_obj.name, num)) 62 63 python = Course('python','6month', 10000) 64 linux = Course('linux','5month', 20000) 65 66 stu1 = Student('EGON', 19, 'MALE') 67 stu1.courses.append(python) 68 stu1.courses.append(linux) 69 70 tea1 = Teacher('ly', 19, 'make', 10) 71 tea1.course = python 72 73 print(tea1.name) 74 print(tea1.course.course_name) 75 76 for i in stu1.courses: 77 print(i) 78 79 print(python.course_name) 80 print(python.course_period) 81 print(python.course_price) 82 83 print(linux.course_name) 84 print(linux.course_period) 85 print(linux.course_price)

浙公网安备 33010602011771号