1. 程式人生 > >Python全棧學習筆記day 24:單繼承、派生、super()、多繼承

Python全棧學習筆記day 24:單繼承、派生、super()、多繼承

一、繼承

class A:pass            父類,基類,超類
class B:pass            父類,基類,超類
class AB_son(A,B):pass   子類,派生類
class A_son(A):pass    子類,派生類


print(A_son.__bases__)         (<class '__main__.A'>,)
print(AB_son.__bases__)        (<class '__main__.A'>, <class '__main__.B'>)
print(A.__bases__)             (<class 'object'>,)

__bases__  檢視繼承的父類
一個類可以被多個類繼承,一個類可以繼承多個父類,沒有繼承父類預設繼承object

在開發程式的過程中,如果我們定義了一個類A,然後又想新建立另外一個類B,但是類B的大部分內容與類A的相同時

我們不可能從頭開始寫一個類B,這就用到了類的繼承的概念。

通過繼承的方式新建類B,讓B繼承A,B會‘遺傳’A的所有屬性(資料屬性和函式屬性),實現程式碼重用

人狗大戰的栗子:

class Animal:
    '''
    人和狗都是動物,所以創造一個Animal基類
    '''
    def __init__(self, name, aggressivity, life_value):
        self.name = name                   人和狗都有自己的暱稱;
        self.aggressivity = aggressivity   人和狗都有自己的攻擊力;
        self.life_value = life_value       人和狗都有自己的生命值;

    def eat(self):
        print('%s is eating'%self.name)

class Dog(Animal):
    pass

class Person(Animal):
    pass

egg = Person('egon',10,1000)
ha2 = Dog('二愣子',50,1000)
egg.eat()
ha2.eat()

二、派生

1、父類中沒有的屬性 在子類中出現 叫做派生屬性
2、父類中沒有的方法 在子類中出現 叫做派生方法
3、只要是子類的物件呼叫,子類中有的名字 一定用子類的,子類中沒有才找父類的,如果父類也沒有報錯
4、如果父類、子類都有就用子類的
   如果還想用父類的,單獨呼叫父類的:
          父類名.方法名 需要自己傳self引數
          super().方法名 不需要自己傳self
5、正常的程式碼中 單繼承 == 減少了程式碼的重複

人狗大戰中派生的栗子(看栗子就懂了):在子類中使用父類中的__init__方法一:
class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp

    def eat(self):
        print('吃藥回血')
        self.hp+=100

class Dog(Animal):
    def __init__(self,name,aggr,hp,kind):
        Animal.__init__(self,name,aggr,hp)     使用父類中的__init__方法一,切記要穿引數self
        self.kind = kind                    派生屬性
    def eat(self):
        Animal.eat(self)      如果既想實現新的功能也想使用父類原本的功能,還需要在子類中再呼叫父類,切記要穿引數self
        self.teeth = 2
    def bite(self,person):                   派生方法
        person.hp -= self.aggr

jin = Dog('金老闆',100,500,'吉娃娃')
jin.eat()
print(jin.hp)

三、瞭解super()

(看栗子就懂了):在子類中使用父類中的__init__方法二:

class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp
    def eat(self):
        print('吃藥回血')
        self.hp+=100

class Dog(Animal):
    def __init__(self,name,aggr,hp,kind):
        super().__init__(name,aggr,hp)   使用父類中的__init__方法二,只在新式類中有,python3中所有類都是新式類
        self.kind = kind                 派生屬性
    def eat(self):print('dog eating')

jin = Dog('金老闆',200,500,'teddy')
print(jin.name)
jin.eat()
super(Dog,jin).eat()         super(子類,物件).父類中藥繼承的方法

四、多繼承

單繼承 : 子類有的用子類 子類沒有用父類
多繼承中,我們子類的物件呼叫一個方法,預設是就近原則,
經典類中 深度優先
新式類中 廣度優先
python2.7 新式類和經典類共存,新式類要繼承object
python3   只有新式類,預設繼承object
經典類和新式類還有一個區別  mro方法只在新式類中存在
super 只在python3中存在
super的本質 :不是單純找父類 而是根據呼叫者的節點位置的廣度優先順序來的

4.1  鑽石繼承

理解super:

class A(object):
    def func(self): print('A')

class B(A):
    def func(self):
        super().func()
        print('B')

class C(A):
    def func(self):
        super().func()
        print('C')

class D(B,C):
    def func(self):
        super().func()
        print('D')
b = D()
b.func()
print(B.mro())



A
C
B
D
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]

總結:

抽象:抽象即抽取類似或者說比較像的部分。是一個從具題到抽象的過程。
繼承:子類繼承了父類的方法和屬性
派生:子類在父類方法和屬性的基礎上產生了新的方法和屬性