面向对象编程的继承和多态
一.继承(重要)
1.什么是继承?
继承就是一种新建类的方法,新建的类叫做子类或者父类,被继承的类我们叫做父类或者基类。
1 class ParentClass1: # 定义父类 2 pass 3 4 5 class ParentClass2: # 定义父类 6 pass 7 8 9 class SubClass1(ParentClass1): # 单继承,基类是ParentClass1,派生类是SubClass 10 pass 11 12 13 class SubClass2(ParentClass1, ParentClass2): # python支持多继承,用逗号分隔开多个继承的类 14 pass 15 16 17 print(SubClass1.__bases__) # 查看所有继承的父类 18 print(SubClass2.__bases__) # 查看所有继承的父类
2.为什么要用继承?
类解决了对象与对象之间代码冗余问题
继承解决的是类与类之间代码冗余问题
3.如何使用继承?
新式类:继承了object类的子子孙孙类都是新式类
经典类:没有继承了object类的子子孙孙类都是经典类
1.只有在python2中才分新式类和经典类,python3中统一都是新式类
2.在python2中,没有显式的继承object类的类,以及该类的子类,都是经典类
3.在python2中,显式地声明继承object的类,以及该类的子类,都是新式类
4.在Python3中,无论是否继承object,都默认继承object,即python3中所有类均为新式类
二.类的继承
通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。
当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生是人。
1 # 类的继承 2 # 父类公共类 3 class People: 4 school = 'SH' 5 6 def __init__(self, name, age, gender): 7 self.name = name 8 self.age = age 9 self.gender = gender 10 11 12 class Student(People): 13 def __init__(self, name, age, gender, course=None): 14 if course is None: 15 course = [] 16 People.__init__(self, name, age, gender) 17 self.course = course 18 19 def choose_course(self, course): 20 self.course.append(course) 21 print('%s选课成功 %s' % (self.name, self.course)) 22 23 24 class Teacher(People): 25 def __init__(self, name, age, gender, level): 26 self.level = level 27 People.__init__(self, name, age, gender) 28 29 def score(self, stu_obj, score): 30 stu_obj.score = score 31 print('%s给%s打了%s分' % (self.name, stu_obj.name, score)) 32 33 34 stu1 = Student('jason', 18, 'male') 35 tea = Teacher('jack', 18, 'female', '初级') 36 # print(Student.choose_course(stu1, 'python')) 37 stu1.choose_course('python') 38 Teacher.score(tea, stu1, 90) 39 print(stu1.__dict__)
三.单继承下属性查找
单属性查找的顺序就是现在对象中查找先在对象中查找,没找到再去产生对象的类中查找,没找到的话再去父类中查找。
1 class Foo: 2 def f1(self): # _Foo__f1() 3 print('Foo.f1') 4 5 def f2(self): 6 # 7 print('Foo.f2') 8 self.f1() # _Foo__f1() 9 10 11 class Bar(Foo): 12 def f1(self): # # _Bar__f1() 13 print('Bar.f1') 14 15 16 obj = Bar() # {} 17 obj.f2()
四.多属性查找
新式类:按照广度有限查询,如图
经典类:按照深度优先查询
1 class A(object): 2 def test(self): 3 print('from A') 4 5 6 class B(A): 7 def test(self): 8 print('from B') 9 10 pass 11 12 13 class C(A): 14 def test(self): 15 print('from C') 16 17 18 class D(B): 19 def test(self): 20 print('from D') 21 pass 22 23 24 class E(C): 25 def test(self): 26 print('from E') 27 28 29 class F(D, E): 30 pass 31 32 33 f1 = F() 34 f1.test() 35 print(F.mro())
五.super()和mro列表
1 class Student: 2 school = 'SH' 3 4 def __init__(self, name, age, gender): 5 self.name = name 6 self.age = age 7 self.gender = gender 8 9 10 class Teacher(Student): 11 def __init__(self, name, age, gender, level): 12 self.level = level 13 super().__init__(name, age, gender) # super的使用 14 15 def score(self, stu_obj, score): 16 stu_obj.score = score 17 print('%s给%s打了%s分' % (self.name, stu_obj.name, score)) 18 19 20 stu = Student('jason', 18, 'male') 21 tea = Teacher('jack', 18, 'female', '初级') 22 tea.score(stu, 80) 23 24 # mro列表练习1 25 class A: 26 def test(self): 27 print('from A.test') 28 super().test() 29 30 31 class B: 32 def test(self): 33 print('from B') 34 35 36 class C(A, B): 37 pass 38 39 40 c = C() 41 c.test() 42 43 44 45 class B: 46 def test(self): 47 print('B---->test') 48 49 def aaa(self): 50 print('B---->aaa') 51 52 53 class A: 54 def test(self): 55 print('A---->test') 56 # super().aaa() 57 58 59 class C(A, B): 60 def aaa(self): 61 print('C----->aaa') 62 63 64 c = A() 65 c.test() # 打印结果:A---->test 66 print(A.mro())
六.多态与多态性
class Animal: def eat(self): print('%s吃' % self.name) def drink(self): print('%s喝' % self.name) def shit(self): print('%s拉' % self.name) def pee(self): print('%s尿尿' % self.name) class Dog(Animal): def __init__(self, name): self.name = name self.bread = '狗狗' def Call(self): print('汪汪汪') class Cat(Animal): def __init__(self, name): self.name = name self.bread = '猫' def Call(self): print('喵喵喵') # c1 = Dog('小白狗') # c1.eat() # c1.Call() c2 = Cat('小白猫') c2.pee() c2.Call()