加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python 23 继承

发布时间:2020-12-20 12:45:22 所属栏目:Python 来源:网络整理
导读:继承--inheritance 面向对象的的三大特征:继承、封装、多态。 1. 面向对象继承: ? 如果B类继承A类,B类就称为子类、派生类,A类就称为父类、超类、基类。 继承的优点: 1. 减少重复代码; 2. 增加了类的耦合性; 3. 使代码清晰、流畅。 2. 单继承 2.1 类名

继承--inheritance

面向对象的的三大特征:继承、封装、多态。

1. 面向对象继承:

? 如果B类继承A类,B类就称为子类、派生类,A类就称为父类、超类、基类。

继承的优点:

1. 减少重复代码;
    2. 增加了类的耦合性;
    3. 使代码清晰、流畅。

2. 单继承

2.1 类名执行父类的属性、方法

# 类名.属性/方法

2.2 子类对象执行父类的属性、方法

# 实例化子类对象
# 对象.属性/方法

class Animal:

    live = '有生命的'
    def __init__(self,name,sex,age):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print("都需进食")

class Human(Animal):
    # pass
    body = '有头'

print(Human.live)
Human.eat(1)

obj = Human('meet','男',30)
print(obj.live)
print(obj.body)
obj.eat()

2.3 执行顺序

# 单项不可逆:实例化对象时必须执行__init__方法,如果子类没有,从父类找,父类没有,从object类中找。
# 如果是 对象.方法,会先从自己的类找方法,自己类没有,才能执行父类中的方法。

2.4 既要执行子类的方法,又要执行父类的方法

# 当子类中也有__init__方法时,如何能够调用父类的方法?

# 方法一: 不依赖继承
# 在子类的__init__中调用父类__init__函数,并且将相应的参数传入。  
#  父类名.__init__(self(对象),其他参数)

class Animal:

    live = '有生命的'
    def __init__(self,age):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print("动物都需进食")

class Human:   # 不依赖继承

    body = '有头'
    def __init__(self,age,hobby):
        Animal.__init__(self,age)
        self.hobby = hobby

obj = Human("meet","男",20,"旅游")
print(obj.__dict__)
# 方法二: 依赖继承
# 在子类中,使用super实现
super(类名,self).__init__(参数)    #完整写法
super().__init__(参数)       # 执行父类的__init__方法,重构父类的方法。
super().方法名()

class Animal:

    live = '有生命的'
    def __init__(self,age):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print("动物都需进食")

class Human(Animal):   # 依赖继承
    
    body = '有头'
    def __init__(self,hobby):
        # super(Human,self).__init__(name,age)
        super().__init__(name,age)
        self.hobby = hobby

    def eat(self):
        super().eat()
        print(f'{self.name}都需吃饭')

obj = Human("meet","旅游")
print(obj.__dict__)
obj.eat()

2.5 单继承执行顺序练习题

# 1
class Base:
    def __init__(self,num):
        self.num = num
    def func1(self):
        print(self.num)

class Foo(Base):
    pass
obj = Foo(123)
obj.func1() # 123 运?的是Base中的func1  

# 2      
class Base:
    def __init__(self,num):
        self.num = num
    def func1(self):
        print(self.num)
class Foo(Base):
    def func1(self):
        print("Foo. func1",self.num)
obj = Foo(123)
obj.func1() # Foo. func1 123 运?的是Foo中的func1           
# 3
class Base:
    def __init__(self,num):
        self.num = num
    def func1(self):
        print(self.num)
        self.func2()
    def func2(self):
        print("Base.func2")
class Foo(Base):
    def func2(self):
    print("Foo.func2")
obj = Foo(123)
obj.func1() # 123 Foo.func2 func1是Base中的 func2是?类中的 

# 4
class Base:
    def __init__(self,num):
        self.num = num
    def func1(self):
        print(self.num)
        self.func2()
    def func2(self):
        print(111,self.num)
class Foo(Base):
    def func2(self):
        print(222,self.num)
lst = [Base(1),Base(2),Foo(3)]
for obj in lst:
    obj.func2() # 111 1 | 111 2 | 222 3

# 5
class Base:
    def __init__(self,Foo(3)]
for obj in lst:
    obj.func1()    # 1 111 1 | 2 111 2 | 3 222 3

3. 多继承

python的类分为两种:
    python2x:在python2.2之前都是经典类,python2.2后,经典类与新式类共存。
    python3x:全部都是新式类。
class ShenXian: # 神仙
    def fei(self):
        print("神仙都会?")
class Monkey: # 猴
    def chitao(self):
        print("猴?喜欢吃桃?")
class SunWukong(ShenXian,Monkey): # 孙悟空是神仙,同时也是?只猴
    pass
sxz = SunWukong() # 孙悟空
sxz.chitao() # 会吃桃?
sxz.fei() # 会?

3.1 经典类

不继承object类,深度优先原则(从左往右,找到底)

类的MRO: Foo-> H -> G -> F -> E -> D -> B -> A -> C.

? 从头开始. 从左往右. ?条路跑到头,然后回头. 继续?条路跑到头. 就是经典类的MRO算法.

3.2 新式类

继承object,mro算法(C3)
mro(Child(Base1,Base2))=[ Child ] + merge( mro(Base1),mro(Base2),[ Base1,Base2] )
(其中Child继承自Base1,Base2)

# 如计算merge( [E,O],[C,E,F,[C] )
有三个列表 :  ①      ②          ③
1.merge不为空,取出第一个列表列表①的表头E,进行判断                各个列表的表尾分别是[O],[E,O],E在这些表尾的集合中,因而跳过当前当前列表
2.取出列表②的表头C,进行判断
   C不在各个列表的集合中,因而将C拿出到merge外,并从所有表头删除c
merge( [E,[C]) = [C] + merge( [E,O] )
                              = [C,E] + merge([0],[F,0])
                              = [C,F] + merge([0],[0])
                              = [C,O]
                              

表头:
  列表的第一个元素
表尾: 
  列表中表头以外的元素集合(可以为空)
示例 
  列表:[A,B,C] 
  表头是A,表尾是B和C
print(子类.mro())    # 查看子类的执行、查找顺序
class A:
    pass
class B(A):
    pass
class C(A):
    pass
class D(A):
    pass
class E(B,C):
    pass
class F(C,D):
    pass
class G(D):
    pass
class H(E,F):
    pass
class I(F,G):
    pass
class K(H,I):
    pass

# print(K.mro())
如果这是经典类,请写出他的继承顺序。(见下图。)
K->H->E->B->A->C->F->D->I->G
如果这是新式类,请写出他的继承顺序,并写出具体过程。

"""
mro(Child(Base1,Base2))=[ Child ] + merge( mro(Base1),Base2] )
mro(K(H,I)) = [K] + merge(mro(H),mro(I),[H,I])
mro(H) = mro(H(E,F))
       = [H] + merga(mro(E),mro(F))
       
       = [H] + merga([E,C,A],D,F])
       = [H,E] + merga([B,[F])
       = [H,B] + merga([C,F] + merga([C,A])
       = [H,A]
       
mro(E) = mro(E(B,C))
       = [E] + merga(mro(B),mro(C))
       = [E] + merga([B,[B,C])
       = [E,A]
mro(F) = mro(F(C,D))
       = [F] + merga(mro(C),mro(D))
       = [F] + merga([C,[D,D])
       = [F,A]
       
mro(B) = mro(B(A))
       = [B,A]
mro(C) = mro(C(A))
       = [C,A]
mro(D) = mro(D(A))
       = [D,A]

mro(I) = mro(I(F,G))
       = [I] + merga(mro(F),mro(G),G])
       
       = [I] + merga([F,[G,G])
       = [I,[G])
       = [I,C] + merga([D,G,A] 
       
mro(G) = mro(G(D))
       = [G,A]

总式:       
mro(K(H,I)) = [K] + merga([H,[I,I])
            = [K,H] + merga([E,[I])  
            = [K,H,[I])
            = [K,B] + merga([F,[I]) 
            = [K,I] + merga([F,A]) 
            = [K,I,A] 

"""

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读