一、继承 1、什么是继承 继承是一种新建类的方式,新建的类称为子类,被继承的类称为父类 继承的特性是:子类会遗传父类的属性 强调:继承是类与类之间的关系 2、为什么用继承 继承的好处就是可以减少代码的冗余 3、如何用继承 在python中支持一个类同时继承多个父类 在python3中 如果一个类没有继承任何类,那默认继承object类 在python2中: 如果一个类没有继承任何类,不会继承object类 新式类 但凡继承了object的类以及该类的子类,都是新式类 经典类 没有继承object的类以及该类的子类,都是经典类 在python3中都是新式类,只有在python2中才区别新式类与经典类 新式类vs经典类? class Parent1(object): pass class Parent2(object): pass class Sub1(Parent1,Parent2): pass # print(Sub1.__bases__) print(Parent1.__bases__) print(Parent2.__bases__)
应用:
#派生:子类中新定义的属性,子类在使用时始终以自己的为准 class OldboyPeople: school = 'oldboy' def __init__(self,name,age,sex): self.name = name #tea1.name='egon' self.age = age #tea1.age=18 self.sex = sex #tea1.sex='male' class OldboyStudent(OldboyPeople): def choose_course(self): print('%s is choosing course' %self.name) class OldboyTeacher(OldboyPeople): # tea1,'egon',18,'male',10 def __init__(self,name,age,sex,level): # self.name=name # self.age=age # self.sex=sex OldboyPeople.__init__(self,name,age,sex) self.level=level def score(self,stu_obj,num): print('%s is scoring' %self.name) stu_obj.score=num stu1=OldboyStudent('耗哥',18,'male') tea1=OldboyTeacher('egon',18,'male',10) #对象查找属性的顺序:对象自己-》对象的类-》父类-》父类。。。 # print(stu1.school) # print(tea1.school) # print(stu1.__dict__) # print(tea1.__dict__) tea1.score(stu1,99) print(stu1.__dict__) 指名道姓访问某一个类的函数:该方式与继承无关
二、组合
1、什么是组合 组合就是一个类的对象具备某一个属性,该属性的值是指向另外外一个类的对象 2、为何用组合 组合也是用来解决类与类直接代码冗余问题的 3、如何用组合 class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,stu_id): OldboyPeople.__init__(self,name,age,sex) self.stu_id=stu_id def choose_course(self): print('%s is choosing course' %self.name) class OldboyTeacher(OldboyPeople): def __init__(self, name, age, sex, level): OldboyPeople.__init__(self,name,age,sex) self.level=level def score(self,stu,num): stu.score=num print('老师[%s]为学生[%s]打分[%s]' %(self.name,stu.name,num)) stu1=OldboyStudent('猪哥',19,'male',1) tea1=OldboyTeacher('egon',18,'male',10) stu1.choose_course() tea1.score(stu1,100) print(stu1.__dict__) ''' class Course: def __init__(self,name,period,price): self.name=name self.period=period self.price=price def tell_info(self): msg=""" 课程名:%s 课程周期:%s 课程价钱:%s """ %(self.name,self.period,self.price) print(msg) class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,stu_id): OldboyPeople.__init__(self,name,age,sex) self.stu_id=stu_id def choose_course(self): print('%s is choosing course' %self.name) class OldboyTeacher(OldboyPeople): def __init__(self, name, age, sex, level): OldboyPeople.__init__(self,name,age,sex) self.level=level def score(self,stu,num): stu.score=num print('老师[%s]为学生[%s]打分[%s]' %(self.name,stu.name,num)) 创造课程 python=Course('python全栈开发','5mons',3000) linux=Course('linux运维','5mons',800)
菱形问题
1、菱形继承 当一个子继承多个父类时,多个父类最终继承了同一个类,称之为菱形继承 2、菱形继承的问题: python2区分经典类与新式类,如果子的继承是一个菱形继承,那么经典类与形式的区别为? 经典类下查找属性:深度优先查找 新式类下查找属性:广度优先查找 class G(object): # def test(self): # print('from G') pass class E(G): # def test(self): # print('from E') pass class B(E): # def test(self): # print('from B') pass class F(G): # def test(self): # print('from F') pass class C(F): # def test(self): # print('from C') pass class D(G): # def test(self): # print('from D') pass class A(B,C,D): def test(self): print('from A') # pass obj=A() print(A.mro()) # obj.test() #A->B->E-C-F-D->G-object
在子派生中重用父类功能的两种方式
在子派生的新方法中重用父类功能的两种方式 方式一:与继承无关 指名道姓法,直接用:类名.函数名 class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,stu_id): OldboyPeople.__init__(self,name,age,sex) self.stu_id=stu_id def choose_course(self): print('%s is choosing course' %self.name) 方式二:严格以来继承属性查找关系 super()会得到一个特殊的对象,该对象就是专门用来访问父类中的属性的(按照继承的关系) super().__init__(不用为self传值) 注意: super的完整用法是super(自己的类名,self),在python2中需要写完整,而python3中可以简写为super() class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,stu_id): # OldboyPeople.__init__(self,name,age,sex) super(OldboyStudent,self).__init__(name,age,sex) self.stu_id=stu_id def choose_course(self): print('%s is choosing course' %self.name) stu1=OldboyStudent('猪哥',19,'male',1) print(stu1.__dict__) print(OldboyStudent.mro()) class A: def f1(self): print('A.f1') class B: def f2(self): super().f1() print('B.f2') class C(B,A): pass obj=C() print(C.mro()) #C-》B->A->object obj.f2()
三、多态
1 什么是多态 多态指的是同一种事物的多种形态 水-》冰、水蒸气、液态水 动物-》人、狗、猪 2 为和要用多态 多态性: 继承同一个类的多个子类中有相同的方法名 那么子类产生的对象就可以不用考虑具体的类型而直接调用功能 3 如何用 import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def speak(self): pass @abc.abstractmethod def eat(self): pass # Animal() #强调:父类是用来指定标准的,不能被实例化 class People(Animal): def speak(self): print('say hello') def eat(self): pass class Dog(Animal): def speak(self): print('汪汪汪') def eat(self): pass class Pig(Animal): def speak(self): print('哼哼哼') def eat(self): pass peo1=People() dog1=Dog() pig1=Pig() peo1.speak() dog1.speak() pig1.speak() def my_speak(animal): animal.speak() my_speak(peo1) my_speak(dog1) my_speak(pig1) l=[1,2,3] s='helllo' t=(1,2,3) print(l.__len__()) print(s.__len__()) print(t.__len__()) # def len(obj): # return obj.__len__() print(len(l)) # l.__len__() print(len(s)) #s.__len__() print(len(t)) 鸭子类型 python推崇的是鸭子类型,只要你叫的声音像鸭子,并且你走路的样子也像鸭子,那你就是鸭子 class Disk: def read(self): print('disk read') def write(self): print('disk wirte') class Process: def read(self): print('process read') def write(self): print('process wirte') class File: def read(self): print('file read') def write(self): print('file wirte') obj1=Disk() obj2=Process() obj3=File() obj1.read() obj1.write()