面向对象的内置属性
一,继承
1、什么是继承?
继承一种新建类的的方式,在python中支持一个儿子继承多个爹
新建的类称为子类或者派生类,
父类又可以称为基类或者超类
子类会”遗传“父类的属性
2、为什么要用继承
可以减少代码冗余
3、怎么用继承
class ParentClass1: pass class ParentClass2: pass class Subclass1(ParentClass1): #一个类的括号内的类称之为括号内的类是另一个类的父级,ParentClass1是Subclass1的父级 pass class Subclass2(ParentClass1,ParentClass2): #子级具有父级所有的属性 pass print(Subclass1.__bases__) print(Subclass2.__bases__)
注意:继承是类与类之间的关系,寻找这种关系需要先抽象再继承。
二,派生
派生:子类定义自己新的属性,如果与父类同名,以子类自己的为准 class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def f1(self): print('爹的f1') class OldboyTeacher(OldboyPeople): def change_score(self): print('teacher %s is changing score' %self.name) def f1(self): print('儿子的f1') #派生出新的属性,如果与父类同名,就以子类自己的为准 tea1 = OldboyTeacher('egon', 18, 'male') tea1.f1() #以OldboyTeacher的f1为准
重点:
在子类派生出的新方法中重用父类的功能两种方法
方式一:指名道姓地调用(其实与继承没有什么关系的)
OldboyPeople.__init__(self,name, age, sex) class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def tell_info(self): print(""" ===========个人信息========== 姓名:%s 年龄:%s 性别:%s """ %(self.name,self.age,self.sex)) class OldboyTeacher(OldboyPeople): # tea1,'egon', 18, 'male', 9, 3.1 def __init__(self, name, age, sex, level, salary): # self.name = name # self.age = age # self.sex = sex OldboyPeople.__init__(self,name, age, sex) #指名道姓的调用,这种方法与继承没有任何关联,是一种类似于在一个函数内调用另一个函数的调用 self.level = level self.salary = salary def tell_info(self): OldboyPeople.tell_info(self) print(""" 等级:%s 薪资:%s """ %(self.level,self.salary)) tea1 = OldboyTeacher('egon', 18, 'male', 9, 3.1) #调用另一个函数时就要遵循函数的调用规则,有多少位参数就要为该函数传多少参数 # print(tea1.name, tea1.age, tea1.sex, tea1.level, tea1.salary) tea1.tell_info()
方式二:super()调用(严格依赖于继承)
#super()的返回值是一个特殊的对象,该对象专门用来调用父类中的属性
#了解:在python2中,需要super(自己的类名,self) class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def tell_info(self): print(""" ===========个人信息========== 姓名:%s 年龄:%s 性别:%s """ %(self.name,self.age,self.sex)) class OldboyTeacher(OldboyPeople): # tea1,'egon', 18, 'male', 9, 3.1 def __init__(self, name, age, sex, level, salary): # OldboyPeople.__init__(self,name, age, sex) super(OldboyTeacher,self).__init__(name,age,sex) #使用super方法,调用父类中的一个属性 self.level = level self.salary = salary def tell_info(self): # OldboyPeople.tell_info(self) super().tell_info() #使用super方法,调用父类中的一个属性 print(""" 等级:%s 薪资:%s """ %(self.level,self.salary)) tea1 = OldboyTeacher('egon', 18, 'male', 9, 3.1) # print(tea1.name, tea1.age, tea1.sex, tea1.level, tea1.salary) tea1.tell_info()
了解知识点:
1、新式类: 继承object的类,以及该类的子类,都是新式类 在python3中,如果一个类没有指定继承的父类,默认就继承object 所以说python3中所有的类都是新式类 2、经典类(只有在python2才区分经典类与新式类): 没有继承object的类,以及该类的子类,都是经典类
两种类的区别在于查找顺序
在菱形继承的背景下,查找属性
1、经典类:深度优先
2、新式类:广度优先
例: class A: def test(self): print('from A') pass class B(A): def test(self): print('from B') class C(A): def test(self): print('from C') class D(B): def test(self): print('from D') class E(C): def test(self): print('from E') class F(D,E): def test(self): print('from F') f1=F() f1.test() #调用mor()方法可以查看子类的查找顺序,F->D->B->E->C-A->object print(F.mro())
!!!!super()会严格按照mro列表从当前查找到的位置继续往后查找 class A: def test(self): print('A.test') super().f1() class B: def f1(self): print('from B') class C(A,B): pass c=C() print(C.mro()) #C->A->B->object c.test()