继承应用模板
学生选课系统案例模板
class Student:
school = "虹桥校区"
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def choose(self):
print("%s 选课成功" % self.name)
stu1 = Student("lili", 18, "female")
stu2 = Student("nana", 16, "female")
stu3 = Student("dada", 19, "male")
class Teacher:
school = "虹桥校区"
def __init__(self, name, age, gender, level):
self.name = name
self.age = age
self.gender = gender
self.level = level
def score(self):
print("%s 正在为学生打分" % self.name)
tea1 = Teacher("egon", 18, "male", 10)
tea2 = Teacher("lxx", 26, "male", 3)
派生
在子类派生的新方法中重用父类的功能
继承了父类的功能后,子类定义了新的功能这种形式称为派生
方式一:指名道姓地引用某一类的函数,与继承无关
class Abb:
school = "虹桥校区"
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Student(Abb):
def choose(self):
print("%s 选课成功" % self.name)
stu1 = Student("lili", 18, "female")
stu2 = Student("nana", 16, "female")
stu3 = Student("dada", 19, "male")
# 继承了父类的功能后,子类定义了新的功能这种形式称为派生
class Teacher(Abb):
def __init__(self, name, age, gender, level): # 形参
Abb.__init__(self, name, age, gender) # 实参
self.level = level
def score(self):
print("%s 正在为学生打分" % self.name)
tea1 = Teacher("egon", 18, "female", 10)
tea2 = Teacher("biu", 19, "male", 20)
print(tea1.__dict__)
super应用
方式二:super()返回一个特殊的对象,该对象会参考发起属性查找的那一个类的mro列表.去当前类的父类中找属性
class Abb:
school = "虹桥校区"
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Student(Abb):
def choose(self):
print("%s 选课成功" % self.name)
stu1 = Student("lili", 18, "female")
stu2 = Student("nana", 16, "female")
stu3 = Student("dada", 19, "male")
# 继承了父类的功能后,子类定义了新的功能这种形式称为派生
class Teacher(Abb):
def __init__(self, name, age, gender, level): # 形参
# Abb.__init__(self, name, age, gender) # 实参
super().__init__(name, age, gender) # super()返回一个特殊的对象,该对象会参考自己当前所在的那一个类的mro列表.去当前类的父类中找属性
# super(Teacher,self).__init__(name, age, gender) python2中的用法
self.level = level
def score(self):
print("%s 正在为学生打分" % self.name)
tea1 = Teacher("egon", 18, "female", 10)
tea2 = Teacher("biu", 19, "male", 20)
print(tea1.__dict__)
继承属性查找
单继承的查找顺序,经典类,新式类的查找顺序式一样的
mro()会显示类的继承顺序,mor列表会按照从左到右开始查找父类,直到找到第一个匹配这个属性的类为止
class C:
x = 222
class B(C):
pass
class A(B):
pass
obj = A()
print(obj.x)
print(A.mro()) # [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>]
print(B.mro()) # [<class '__main__.B'>, <class '__main__.C'>, <class 'object'>]
多继承背景下
如果新式类与经典类最后没有汇聚到一个点上,那么查找的顺序也是一样的,都是先从一个分支的深度查找
新式类,经典类多继承背景菱形继承查找顺序的差别
菱形继承/钻石继承:一个子类继承的多条分支,最终汇聚在一个非object的类上
经典类:深度优先
新式类:广度优先
新式类菱形继承查找代码呈现
class G(object):
def test(self):
print('from G')
class E(G):
def test(self):
print('from E')
class F(G):
def test(self):
print('from F')
class B(E):
def test(self):
print('from B')
class C(F):
def test(self):
print('from C')
class D(G):
def test(self):
print('from D')
class A(B, C, D):
def test(self):
print('from A')
pass
obj = A()
obj.test() # 查找顺序为:obj->A->B->E->C->F->D->G->object
案例:
class A:
def test(self):
print("from A")
super().test()
class B:
def test(self):
print("from B")
class C(A, B): # 查找顺序[C,A,B,object]
pass
obj = C()
obj.test()
from A
from B
obj = A() # 查找顺序[A,object]
obj.test()
from A ,object 里面没有test()所以会报错
注意:新式类里面的查找顺序,以属性发起者优先,找不到会从发起者的父类里面去找属性,
如果父类里面没有,会从第二个父类里面查找,应当遵循广度优先的原则
mixins机制(多继承的命名规范)
继承表达的是一个is-a的关系(尽可能的让一个子类归属一个父类,大量的重复代码都放在父类里面,把父类放在最右边,其他的父类主要用来添加功能)
代码呈现
class Vehicle:
pass
class FlyableMixin:
def fly(self):
print("flying")
class CivilAircraft(FlyableMixin, Vehicle):
pass
class Helicopter(FlyableMixin, Vehicle):
pass
class Car(Vehicle):
pass
组合
组合:组合表达的是一个has-a的关系,一个对象的属性是值是指向另外一个类的对象
class Abb:
school = "虹桥校区"
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Student(Abb):
def choose(self):
print("%s 选课成功" % self.name)
# 继承了父类的功能后,子类定义了新的功能这种形式称为派生
class Teacher(Abb):
def __init__(self, name, age, gender, level): # 形参
Abb.__init__(self, name, age, gender) # 实参
self.level = level
def score(self):
print("%s 正在为学生打分" % self.name)
class Course:
def __init__(self, name, price, period):
self.name = name
self.price = price
self.period = period
def tell(self):
print("课程信息:%s %s %s" % (self.name, self.price, self.period))
python = Course("python", 20000, "6mons")
linux = Course("linux", 20000, "5mons")
stu1 = Student("lili", 18, "female")
stu2 = Student("nana", 16, "female")
stu3 = Student("dada", 19, "male")
tea1 = Teacher("egon", 18, "female", 10)
tea2 = Teacher("biu", 19, "male", 20)
# stu1.course = python
# stu1.course.tell()
stu1.courses = []
stu1.courses.append(python)
stu1.courses.append(linux)
print(stu1.courses)
for course_obj in stu1.courses:
course_obj.tell()