天天看點

python面向對象 : 繼承

一. 初識繼承

  繼承是一種建立新類的方式,在python中,建立的類可以繼承一個或多個父類,父類又可稱為基類或超類,建立的類稱為派生類或子類.

  當我們在定義多個類的時候,發現要用到相同的方法或變量,如果每個類都要寫相同的方法和變量,那麼代碼就會重複,為了減少代碼,可以用繼承來解決.

# 三個類中都有相同的參數,造成代碼重複

class Person:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age

class Cat:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age

class Dog:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age      

  用繼承的思想來做

class Animal:
    animal = '動物'
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

    def hobby(self):
        print('%s喜歡吃' % self.name)

class Person(Animal):  #繼承Animal類
    pass
class Cat(Animal):
    pass
class Dog(Animal):
    pass

print(Person.animal)  #動物  類名可以通路父類所有内容
p = Person('jack', '男', 25)
p.hobby()  #jack喜歡吃
# 子類以及子類執行個體化的對象 可以通路父類的任何方法或變量.先從本類中找hobby方法,找不到則從父類裡找      
既要執行子類的方法,又要執行父類的方法? 有兩種解決方法.
      1,Animal.__init__(self, name, sex, age)
      2,super().__init__(name,sex,age)
      
class Animal:
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):
        print('%s會吃' % self.name)

    def drink(self):
        print('%s會喝' % self.name)


class Bird(Animal):
    def __init__(self, name, sex, age, wing):
        # super().__init__(name, sex, age )  #自動把self傳給父類
        Animal.__init__(self, name, sex, age)
        self.wing = wing

    def egg(self):
        print('雞會下蛋')

    def eat(self):  #本類含有和弗雷相同的方法名
        super().drink()  #用super()調用父類的方法
        print('鳥會吃蟲子')


b = Bird('鳥', '公', 30, '翅膀')
print(b.__dict__)  # {'name': '鳥', 'sex': '公', 'age': 30, 'wing': '翅膀'}
b.eat()  
# 鳥會喝    #執行父類的eat方法
# 鳥會吃蟲子   #執行本類的eat方法      

二. 繼承的進階

1. 單繼承和多繼承

class A:
    pass
class B(A):  #單繼承
    pass
class C(A):
    pass
class D(B,C):  #多繼承
    pass      

2. 經典類, 新式類 

  新式類: 凡是繼承object類都是新式類. python3x 所有的類都是新式類,因為python3x中的類都預設繼承object.

  經典類: 不繼承object類都是經典類, python2x:(既有新式類,又有經典類) 所有的類預設都不繼承object類,所有的類預設都是經典類.你可以讓其繼承      object.

單繼承: 新式類,經典類查詢順序一樣.
      
多繼承繼承順序(讨論的是繼承兩個類):
       新式類: 遵循廣度優先 : 一條路走到倒數第二級,判斷,如果其他路能走到終點,則傳回走另一條路.如果不能,則走到終點. 可以用mro()來查詢繼承順序.      
經典類: 遵循深度優先 : 一條路走到底.
      
class A:
    def func(self):
        print('IN A')

class B(A):
    # pass
    def func(self):
        print('IN B')

class C(A):
    # pass
    def func(self):
        print('IN C')

class D(B):
    # pass
    def func(self):
        print('IN D')

class E(C):
    def func(self):
        print('IN E')

class F(D,E):
    # pass
    def func(self):
        print('IN F')

f1 = F()
f1.func()  #IN F

print(F.mro())  # 查詢類的繼承順序
# [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, 
# <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]      

 3. 多繼承原理: MRO_C算法

 mro():  查詢類的繼承順序.  代碼和步驟如下:
      
class H:
    pass


class G(H):
    pass


class F(H):
    pass


class E(G):
    pass


class D(F):
    pass


class C(E):
    pass


class B(D):
    pass


class A(B, C, D):
    pass


print(A.mro())

'''
首先找到A繼承的三個類的深度繼承順序,放到一個清單中

B   [B,D,F,H]
C   [C,E,G,H]
D   [D,F,H]

每個清單的第一個元素為頭部,其它位置元素都為尾部,從第一個清單的頭部開始找,找其他清單中尾部是否含有
這個類名,如果沒有,提取出來放到一個清單中,如果有,找下一個清單的頭部,循環下去
隻要提取來一個,我們就從第一個清單的頭部接着重複上面的操作.

A   [A][B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D]  A #找到第一個清單的頭A,其他清單尾部沒有A,把A取出來,如果其他清單的頭部有A則剔除
    [][B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D]   B
    [][D,F,H] [C,E,G,H] [D,F,H] [C,D]       C
    [][D,F,H] [E,G,H] [D,F,H] [D]           D
    [][F,H] [E,G,H] [F,H] []                F 
    [][H] [E,G,H] [H] []                    E #找到第一個清單的頭部H,但是其他清單尾部有H,是以跳過這個清單,去下一個清單取頭部
    [][H] [G,H] [H] []                      G
    [][H] [H] [H] []                        H
    [][] [] [] [] 
    lst = [A,B,C,D,F,E,G,H] 
'''      
class F:
    pass


class E:
    pass


class D:
    pass


class C(D, F):
    pass


class B(E, D):
    pass


class A(B, C):
    pass


print(A.mro())
'''
首先找到A繼承的兩個類的深度繼承順序
把B作為子類,找出B類的查詢順序

B   [B] [E] [D] [E,D]  B  
    [] [E] [D] [E,D]   E
    [] [] [D] [D]      D
    [] [] [] []
    lst = [B,E,D]
把C作為子類,找出C類的查詢順序

C   [C] [D] [F] [D,F]  C
    [] [D] [F] [D,F]   D
    [] [] [F] [F]      F
    [] [] [] []       
    lst = [C,D,F]

A   [A] [B,E,D] [C,D,F] [B,C]  A
    [] [B,E,D] [C,D,F] [B,C]   B 
    [] [E,D] [C,D,F] [C]       E
    [] [D] [C,D,F] [C]         C
    [] [D] [D,F] []            D
    [] [] [F] []               F
    [] [] [] []
    lSt = [A,B,E,C,D,F]    
'''      

轉載于:https://www.cnblogs.com/huangqihui/p/9367520.html