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("jack",18,"male")
stu2 = Student("tom",19,"male")
stu3 = Student(‘lili‘,29,"female")
class Teacher: # 定义老师类
school = "虹桥校区"
def __init__(self,name,age,gender,level): # 老师类与学生类功能多一个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‘,38,"male",3)
class People:
school = "虹桥校区" # 将冗余数据放到父类当中
def __init__(self,name,age,gender): # 将学生类和老师类的共同属性放到父类中间解决冗余问题
self.name = name
self.age = age
self.gender = gender
class Student(People):
def choose(self):
print("%s 选课成功" %self.name)
class Teacher(People):
# 定义一个__init__函数是形参
# 空对象,‘egon‘,18,"male",10
def __init__(self,name,age,gender,level): # 老师类多一个level就需要保留
# 调用父类的__init__是函数(实参)不是方法,为老师类的__init__进行传参
People.__init__(self,name,age,gender) # 在子类的派生当中重用父类功能
self.level = level
def score(self):
print("%s 正在为学生打分" %self.name)
stu1 = Student("jack",18,"male")
stu2 = Student("tom",19,"male")
stu3 = Student(‘lili‘,29,"female")
tea1 = Teacher(‘egon‘,18,"male",10) # 空对象,‘egon‘,18,"male",10
tea2 = Teacher(‘lxx‘,38,"male",3)
# print(stu1.school)
# print(stu1.name)
# print(stu1.age)
# print(stu1.gender)
print(tea1.__dict__)
class People:
school = "虹桥校区"
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
class Teacher(People):
# 空对象,‘egon‘,18,"male",10
def __init__(self,name,age,gender,level):
# People.__init__(self,name,age,gender)
super(Teacher,self).__init__(name,age,gender)
self.level = level
def score(self):
print("%s 正在为学生打分" %self.name)
tea1 = Teacher(‘egon‘,18,"male",10) # 空对象,‘egon‘,18,"male",10
print(tea1.__dict__)
# 案例:
class A: # [A,object]
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()
obj1 = A()
obj1.test()
Python中子类可以同时继承多个父类,如A(B,C,D)
如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性
如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先
# 继承顺序
class A(object):
def test(self):
print(‘from A‘)
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‘)
pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性
# 新式类继承顺序:F->D->B->E->C->A
# 经典类继承顺序:F->D->B->A->E->C
# python3中统一都是新式类
# pyhon2中才分新式类与经典类
class G: # 在python2中,未继承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‘)
pass
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() # A->B->E->C->F->D->G->object
# print(A.mro())
obj.test()
python到底是如何实现继承的呢? 对于你定义的每一个类,Python都会计算出一个方法解析顺序(MRO)列表,该MRO列表就是一个简单的所有基类的线性顺序列表,如下
A.mro() # 等同于A.__mro__
[<class ‘__main__.A‘>, <class ‘__main__.B‘>, <class ‘__main__.E‘>, <class ‘__main__.C‘>, <class ‘__main__.F‘>, <class ‘__main__.D‘>, <class ‘__main__.G‘>, <class ‘object‘>]
为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。 而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
# 我们把飞行功能放到交通工具这个父类中是不合理的
class Vehicle: # 交通工具
def fly(self):
‘‘‘
飞行功能相应的代码
‘‘‘
print("I am flying")
class CivilAircraft(Vehicle): # 民航飞机
pass
class Helicopter(Vehicle): # 直升飞机
pass
class Car(Vehicle): # 汽车并不会飞,但按照上述继承关系,汽车也能飞了
pass
class Vehicle: # 交通工具
pass
class FlyableMixin: # 定义一个飞行功能
def fly(self):
print(‘flying‘)
class CivilAircraft(FlyableMixin,Vehicle): # 民航飞机 继承了Flyablemixin就使用它的功能
pass
class Helicopter(FlyableMixin,Vehicle): # 直升飞机
pass
class Car(Vehicle): # 小汽车 不继承就不使用它的功能,也不影响
pass
# ps: 采用这种编码规范(如命名规范)来解决具体的问题是python惯用的套路,大家都照这种规范来
# 这种规范叫什么呢?
# 建议不要用多继承,如果要用到这个继承:把用来表达归属关系的那个类(当然也是最复杂的
# 那个类)往多继承的最右边去放(Vehicle)。把用来添加功能的类往左边放并改名Mixin为后缀
# 的名字(FlyableMixin)这种类的特点是这种类里面就只放功能,并且功能的特点是能独立运行
class People:
school = "虹桥校区"
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
class Student(People):
def choose(self):
print("%s 选课成功" %self.name)
class Teacher(People):
# 空对象,‘egon‘,18,"male",10
def __init__(self,name,age,gender,level):
People.__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全栈开发",19800,"6mons")
linux = Course("linux",19000,"5mons")
# 学生属性
stu1 = Student("jack",18,"male")
stu2 = Student("tom",19,"male")
stu3 = Student(‘lili‘,29,"female")
# 老师属性
tea1 = Teacher(‘egon‘,18,"male",10)
tea2 = Teacher(‘lxx‘,38,"male",3)
stu1.course = python # 假如规定只有pyhton一门课程就直接等于python,这就叫组合
stu1.course.tell() # 直接查看课程信息
stu1.courses = [] # 给学生1添加多门课程
stu1.courses.append(python) # 给学生1添加python课程
stu1.courses.append(linux) # 给学生1添加linux课程
# 此时对象stu1集对象独有的属性、Student类中的内容、Course类中的内容于一身(都可以访问到),
# 是一个高度整合的产物
print(stu1.courses) # 查看学生1所学的多门课程的每一门课程的信息
for course_obj in stu1.courses:
course_obj.tell()
[面向对象之继承应用(在子类派生重用父类功能(super),继承实现原理(继承顺序、菱形问题、继承原理、Mixins机制),组合]
原文:https://www.cnblogs.com/liupengfei1123/p/14678640.html