面向对象之继承等相关内容-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算法

image-20200806210505694

按照上图所示,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

 

posted @ 2020-08-06 21:33  投降输一半!  阅读(124)  评论(0编辑  收藏  举报