面向对象之继承等相关内容-26 1.继承介绍
"""
1 什么是继承
继承是一种新建类的方式,新建的类称之为子类,被继承的类称之为
父类、基类、超类
python支持多继承
2 为何要继承
子类会遗传父类的属性,所以继承是用来解决类与类之间代码冗余问题
3、如何实现继承
"""
# class Parent1:
# pass
#
# class Parent2:
# pass
#
# class Sub1(Parent1):
# pass
#
# class Sub2(Parent1,Parent2):
# pass
#
# print(Sub1.__bases__)
# print(Sub2.__bases__)
#
# 继承案列:
class OldboyPeople:
school = "oldboy"
class Student(OldboyPeople):
def __init__(self,name,age,gender,stud_id,course):
self.name = name
self.age = age
self.gender = gender
self.stu_id = stud_id
self.course = course
def choose(self):
print('%s 正在选课' %self.name)
class Teacher(OldboyPeople):
def __init__(self,name,age,gender,salary,level):
self.name = name
self.age = age
self.gender = gender
self.salary = salary
self.level = level
def score(self,stu,num):
stu.num = num
stu1=Student("艾利克斯",73,'male',1001,"python全栈开放")
tea1=Teacher("egon",18,'male',2000,10)
print(stu1.school)
2.在子类派生的新方法中重用父类的功能方式一
# 在子类派生的新方法中重用父类的功能
# 方式一:指名道姓地调用某一个类的函数
# 特点:不依赖于继承关系
#
class OldboyPeople:
school = "oldboy"
# 空对象,"艾利克斯",73,'male'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def f1(self):
print('1111111')
class Student(OldboyPeople):
# 空对象,"艾利克斯",73,'male',1001,"python全栈开放"
def __init__(self,name,age,gender,stu_id,course):
OldboyPeople.__init__(self,name,age,gender) # OldboyPeople.__init__(空对象,"艾利克斯",73,'male')
self.stu_id = stu_id
self.course = course
def choose(self):
print('%s 正在选课' %self.name)
def f1(self):
OldboyPeople.f1(self)
print("22222")
class Teacher(OldboyPeople):
def score(self,stu,num):
stu.num = num
stu1=Student("艾利克斯",73,'male',1001,"python全栈开放")
# tea1=Teacher("egon",18,'male',2000,10)
stu1.f1()
3.属性查找
# 例1:
# class Foo:
# def f2(self):
# print("Foo.f2")
#
# def f1(self):
# print('Foo.f1')
# self.f2() # obj.f2()
#
#
# class Bar(Foo):
# def f2(self):
# print("Bar.f2")
# obj = Bar()
#
# obj.f1()
"""
Foo.f1
Bar.f2
"""
# 例2:父类如果不想让子类覆盖自己的方法,可以在方法名前加前缀__
class Foo:
def __f2(self): # _Foo__f2
print("Foo.f2")
def f1(self):
print('Foo.f1')
self.__f2() # obj._Foo__f2()
class Bar(Foo):
def __f2(self): # _Bar__f2
print("Bar.f2")
obj = Bar()
obj.f1()
4.继承的实现原理
# coding:utf-8
# 1 补充知识:
# 新式类:但凡是继承了object类的子类,以该子类子子孙孙类都称之为新式类
# 经典类:没有继承了object类的子类,以该子类子子孙孙类都称之为经典类
# python3中全都是新式类,python2中才有经典类:
# 在python3中没有继承任何类的类会默认继承object类
# class Foo(object):
# pass
#
# print(Foo.__bases__)
# 2 继承的实现原理
# 2.1 菱形问题:一个子类继承的多条件分支最终汇聚到一个非object类,在菱形继承下
# 新式类与经典类关于属性查找的方式不同
# 新式类:广度优先
# 经典类:深度优先
# 例1:非菱形继承,经典类与新式类的属性查找顺序都一样
# class E:
# # def test(self):
# # print('from E')
# pass
#
# class F:
# 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:
# def test(self):
# print('from D')
#
#
# class A(B, C, D):
# # def test(self):
# # print('from A')
# pass
#
# obj=A()
# obj.test()
# 例2:菱形继承
class G(object): # 在python2中,未继承object的类及其子类,都是经典类
# def test(self):
# print('from G')
pass
class E(G):
# def test(self):
# print('from E')
pass
class F(G):
# def test(self):
# print('from F')
pass
class B(E):
# def test(self):
# print('from B')
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()
# obj.test()
print(A.mro())
附加 类的继承的底层 C3算法
按照上图所示,C3算法的原理大致是如下会产生4个列表
[A,B,D,E][A,C,D,E][A,D,E][A,B,C,D]
这4个列表分别的意义是 都是从A一路到头的顺序 先按照深度优先画出路线
1. 按照A同时继承的顺序,第一个是 A B D E
2. 按照A同时继承的顺序,第二个是 A C D E
3. 按照A同时继承的顺序,第三个是 A D E
4. 按照A同时继承的顺序,第四个是A的父类排队 A B C D
工作开始
第一步 拿出第一个列表的第一个位置元素 作为第一顺序,确认是否是其余三个列表中的尾部,如果是,放弃查找下一个列表,如果不是,则将作为第一个查找顺序,并在所有列表中去除
A
将得到 现在的四个列表 [B,D,E][C,D,E][D,E][B,C,D]
第二步 拿出现有第一个列表的第一个位置元素 作为第一顺序,确认是否是其余三个列表中的尾部,如果是,放弃查找下一个列表,如果不是,则将作为第一个查找顺序,并在所有列表中去除
A B
将得到 现在的四个列表 [D,E][C,D,E][D,E][C,D]
第三步 拿出现有第一个列表的第一个位置元素 作为第一顺序,确认是否是其余三个列表中的尾部,如果是,放弃查找下一个列表,如果不是,则将作为第一个查找顺序,并在所有列表中去除
当拿出D时候 D是其中一个列表的尾部 那么 跳过第一个列表 从第二个列表中的第一个位置元素开始
就得到C
A B C
将得到 现在的四个列表 [D,E][D,E][D,E][D]
第四步 只剩下 D E两个类了 已经表明 D 继承 E
所以顺序是 A B C D E
按照上图所示,C3算法的原理大致是如下会产生4个列表
[A,B,D,E][A,C,D,E][A,D,E][A,B,C,D]
这4个列表分别的意义是 都是从A一路到头的顺序 先按照深度优先画出路线
1. 按照A同时继承的顺序,第一个是 A B D E
2. 按照A同时继承的顺序,第二个是 A C D E
3. 按照A同时继承的顺序,第三个是 A D E
4. 按照A同时继承的顺序,第四个是A的父类排队 A B C D
工作开始
第一步 拿出第一个列表的第一个位置元素 作为第一顺序,确认是否是其余三个列表中的尾部,如果是,放弃查找下一个列表,如果不是,则将作为第一个查找顺序,并在所有列表中去除
A
将得到 现在的四个列表 [B,D,E][C,D,E][D,E][B,C,D]
第二步 拿出现有第一个列表的第一个位置元素 作为第一顺序,确认是否是其余三个列表中的尾部,如果是,放弃查找下一个列表,如果不是,则将作为第一个查找顺序,并在所有列表中去除
A B
将得到 现在的四个列表 [D,E][C,D,E][D,E][C,D]
第三步 拿出现有第一个列表的第一个位置元素 作为第一顺序,确认是否是其余三个列表中的尾部,如果是,放弃查找下一个列表,如果不是,则将作为第一个查找顺序,并在所有列表中去除
当拿出D时候 D是其中一个列表的尾部 那么 跳过第一个列表 从第二个列表中的第一个位置元素开始
就得到C
A B C
将得到 现在的四个列表 [D,E][D,E][D,E][D]
第四步 只剩下 D E两个类了 已经表明 D 继承 E
所以顺序是 A B C D E