面向對象三大特性——繼承(含派生)

1、繼承概念

  繼承指的是類與類之間的關係,繼承的功能之一就是能夠用來解決代碼重用問題。python

一、繼承是什麼?

(1)繼承是一種建立新類的方式編程

(2)在python中,新建的類能夠繼承一個或多個父類(其餘語言只能繼承一個父類),父類又能夠稱爲基類或者超類數據結構

(3)新建的類稱爲派生類或子類。編程語言

二、python中類的繼承分爲:單繼承和多繼承

class ParentClass1:
    pass

class ParentClass2:
    pass

class SubClass1(ParentClass1):  # 單繼承,基類是ParentClass1,派生類是SubClass
    pass

class SubClass2(ParentClass1, ParentClass2):   # 多繼承,用逗號分隔開多個繼承的類
    pass

三、查看繼承: __bases__ 

  __base__:只查看從左到右繼承的第一個子類
  __bases__:查看全部繼承的父類ide

print(ParentClass1.__base__, type(ParentClass1.__base__))
print(SubClass1.__base__, type(SubClass1.__base__))
print(SubClass2.__base__, type(SubClass2.__base__))   # 只查看到第一個父類
"""
<class 'object'> <class 'type'>
<class '__main__.ParentClass1'> <class 'type'>
<class '__main__.ParentClass1'> <class 'type'>
"""

print(SubClass1.__bases__)
print(SubClass2.__bases__)
"""數據結構爲元組
(<class '__main__.ParentClass1'>,)
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
"""

四、經典類與新式類

(1)python2中的經典類和新式類函數

  經典類:沒有顯式繼承object類的類,以及該類的子類都是經典類。spa

  新式類:顯式地聲明繼承object類,以及該類的子類都是新式類。設計

# Python2中經典類:沒有繼承object的類,以及它的子類
class Foo:
    pass

class Bar(Foo):
    pass

# python2中新式類:繼承object的類,以及它的子類都稱爲新式類
class Foo(object):
    pass

class Bar(Foo):
    pass
"""
>>> class Foo:pass
...
>>> Foo.__bases__
()
>>> class Foo(object):pass
...
>>> Foo.__bases__
(<type 'object''>,)
"""

(2)python3只有新式類

  僅在python2中才分新式類和經典類,在python3中,不管是否繼承object,都默認繼承object,即python3中全部類均爲新式類。code

  提示:若是沒有指定基類,python的類會默認繼承object類,object是全部python類的基類,它提供了一些常見方法(如__str__)的實現。對象

# python3中新式類:一個類沒有繼承object類,默認就繼承object
class Foo():
    pass

print(Foo.__bases__)     # (<class 'object'>,)

2、繼承與抽象(先抽象再繼承)

  繼承描述的是子類與父類之間的關係,是一種什麼是什麼的關係。要找出這種關係,必須先抽象再繼承

一、抽象概念

抽象定義抽取相似或者說比較像的部分(也就是提取一類事物的特色,範圍愈來愈大,共性愈來愈少)。

抽象分爲兩個層次:
(1)將奧巴馬和梅西這倆對象比較像的部分抽取成類;
(2)將人,豬,狗這三個類比較像的部分抽取成父類。

抽象最主要的做用是劃分類別(能夠隔離關注點,下降複雜度)

  

二、繼承與抽象關係

  繼承:是基於抽象的結果,經過編程語言去實現它,確定是先經歷抽象這個過程,才能經過繼承的方式去表達出抽象的結構。
  抽象:只是分析和設計的過程當中,一個動做或者說一種技巧,經過抽象能夠獲得類

class Hero:
    def __init__(self, nickname, life_value, aggresivity):
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity

    def attack(self, enemy):
        enemy.life_value -= self.aggresivity

class Garen(Hero):
    pass

class Riven(Hero):
    pass

g1 = Garen('剛哥', 29, 30)
print(g1.__dict__)
"""
{'nickname': '剛哥', 'life_value': 29, 'aggresivity': 30}
"""

3、繼承與重用性

  開發程序的過程當中,若是咱們定義了一個類A,而後又想新創建另一個類B,可是類B的大部份內容與類A的相同時:

  能夠經過繼承的方式新建類B,讓B繼承A,B會‘遺傳’A的全部屬性(數據屬性和函數屬性),實現代碼重用。

class Hero:
    def __init__(self,nickname,aggressivity,life_value):
        self.nickname=nickname
        self.aggressivity=aggressivity
        self.life_value=life_value

    def move_forward(self):
        print('%s move forward' %self.nickname)

    def move_backward(self):
        print('%s move backward' %self.nickname)

    def move_left(self):
        print('%s move forward' %self.nickname)

    def move_right(self):
        print('%s move forward' %self.nickname)

    def attack(self,enemy):
        enemy.life_value-=self.aggressivity
class Garen(Hero):
    pass

class Riven(Hero):
    pass

g1=Garen('草叢倫',100,300)
r1=Riven('銳雯雯',57,200)

print(g1.life_value) #結果:300
r1.attack(g1)
print(g1.life_value) #結果:243
代碼重用示例

  用已經有的類創建一個新的類,這樣就重用了已經有的軟件中的一部分設置大部分,大大節省了編程工做量,這就是常說的軟件重用,不只能夠重用本身的類,也能夠繼承別人的,好比標準庫,來定製新的數據類型,這樣就是大大縮短了軟件開發週期,對大型軟件開發來講,意義重大.

一、屬性查找

  子類有本身的方法,就執行本身的;若是子類沒有本身的方法,就會找父類的。

class Foo:
    def f1(self):
        print('from Foo.f1')

    def f2(self):
        print('from Foo.f2')
        self.f1()


class Bar(Foo):
    def f2(self):
        print('from Bar.f2')

b = Bar()
print(b.__dict__)  # 未定義__init__沒有本身的屬性  字典內爲空
b.f1()   # 指向父類的函數
b.f2()   # 指向子類重用的函數
"""
{}
from Foo.f1
from Bar.f2   # 注意和父類中的區別
"""

4、派生

一、派生概念

  在父類的基礎上產生子類,產生的子類就叫作派生類

二、方法重寫與派生方法

  父類裏有,子類也有的方法,就叫作方法的重寫(就是把父類裏的方法重寫)

class Riven(Hero):
    camp='Noxus'
    def attack(self,enemy): #在本身這裏定義新的attack,再也不使用父類的attack,且不會影響父類
        print('from riven')
    def fly(self): #在本身這裏定義新的
        print('%s is flying' %self.nickname)

  父類裏沒有的方法,在子類中有了,這樣的方法就叫作派生方法

class Riven(Hero):
    camp='Noxus'
    def __init__(self,nickname,aggressivity,life_value,skin):
        Hero.__init__(self,nickname,aggressivity,life_value) #調用父類功能
        self.skin=skin #新屬性
    def attack(self,enemy): #在本身這裏定義新的attack,再也不使用父類的attack,且不會影響父類
        Hero.attack(self,enemy) #調用功能
        print('from riven')
    def fly(self): #在本身這裏定義新的
        print('%s is flying' %self.nickname)

r1=Riven('銳雯雯',57,200,'比基尼')
r1.fly()
print(r1.skin)

'''
運行結果
銳雯雯 is flying
比基尼

'''
相關文章
相關標籤/搜索