Python學習(七)面向對象 ——繼承和多態

Python 類的繼承和多態

 

  Python 類的繼承

    在OOP(Object Oriented Programming)程序設計中,當咱們定義一個class的時候,能夠從某個現有的class 繼承,新的class稱爲子類(Subclass),而被繼承的class稱爲基類、父類或超類(Base class、Super class)。ide

    咱們先來定義一個class Person,表示人,定義屬性變量 name 及 sex (姓名和性別);函數

    定義一個方法print_title():當sex是male時,print man;當sex 是female時,print woman。參考以下代碼:spa

 1 class Person(object):
 2     def __init__(self,name,sex):
 3         self.name = name
 4         self.sex = sex
 5         
 6     def print_title(self):
 7         if self.sex == "male":
 8             print("man")
 9         elif self.sex == "female":
10             print("woman")
11 
12 class Child(Person):                            # Child 繼承 Person
13     pass
14             
15 May = Child("May","female")
16 Peter = Person("Peter","male")
17 
18 print(May.name,May.sex,Peter.name,Peter.sex)    # 子類繼承父類方法及屬性
19 May.print_title()
20 Peter.print_title()

    而咱們編寫 Child 類,徹底能夠繼承 Person 類(Child 就是 Person);使用 class subclass_name(baseclass_name) 來表示繼承;設計

    繼承有什麼好處?最大的好處是子類得到了父類的所有屬性及功能。以下 Child 類就能夠直接使用父類的 print_title() 方法code

    實例化Child的時候,子類繼承了父類的構造函數,就須要提供父類Person要求的兩個屬性變量 name 及 sex:blog

    在繼承關係中,若是一個實例的數據類型是某個子類,那它也能夠被看作是父類(May 既是 Child 又是 Person)。可是,反過來就不行(Peter 僅是 Person,而不是Child)。繼承

    繼承還能夠一級一級地繼承下來,就比如從爺爺到爸爸、再到兒子這樣的關係。而任何類,最終均可以追溯到根類object,這些繼承關係看上去就像一顆倒着的樹。好比以下的繼承樹: it

    

 

  isinstance()   及  issubclass()

    Python 與其餘語言不一樣點在於,當咱們定義一個 class 的時候,咱們實際上就定義了一種數據類型。咱們定義的數據類型和Python自帶的數據類型,好比str、list、dict沒什麼兩樣。io

    Python 有兩個判斷繼承的函數:isinstance() 用於檢查實例類型;issubclass() 用於檢查類繼承。參見下方示例:event

class Person(object):
    pass

class Child(Person):                 # Child 繼承 Person
    pass

May = Child()
Peter = Person()    

print(isinstance(May,Child))         # True
print(isinstance(May,Person))        # True
print(isinstance(Peter,Child))       # False
print(isinstance(Peter,Person))      # True
print(issubclass(Child,Person))      # True

 

  Python 類的多態

     在說明多態是什麼以前,咱們在 Child 類中重寫 print_title() 方法:若爲male,print boy;若爲female,print girl

 1 class Person(object):
 2     def __init__(self,name,sex):
 3         self.name = name
 4         self.sex = sex
 5         
 6     def print_title(self):
 7         if self.sex == "male":
 8             print("man")
 9         elif self.sex == "female":
10             print("woman")
11 
12 class Child(Person):                # Child 繼承 Person
13     def print_title(self):
14         if self.sex == "male":
15             print("boy")
16         elif self.sex == "female":
17             print("girl")
18         
19 May = Child("May","female")
20 Peter = Person("Peter","male")
21 
22 print(May.name,May.sex,Peter.name,Peter.sex)
23 May.print_title()
24 Peter.print_title()

    當子類和父類都存在相同的 print_title()方法時,子類的 print_title() 覆蓋了父類的 print_title(),在代碼運行時,會調用子類的 print_title()

    這樣,咱們就得到了繼承的另外一個好處:多態 

    多態的好處就是,當咱們須要傳入更多的子類,例如新增 Teenagers、Grownups 等時,咱們只須要繼承 Person 類型就能夠了,而print_title()方法既能夠直不重寫(即便用Person的),也能夠重寫一個特有的。這就是多態的意思。調用方只管調用,無論細節,而當咱們新增一種Person的子類時,只要確保新方法編寫正確,而不用管原來的代碼。這就是著名的「開閉」原則:

  •     對擴展開放(Open for extension):容許子類重寫方法函數
  •     對修改封閉(Closed for modification):不重寫,直接繼承父類方法函數

 

  子類重寫構造函數

     子類能夠沒有構造函數,表示同父類構造一致;子類也可重寫構造函數;如今,咱們須要在子類 Child 中新增兩個屬性變量:mother 和 father,咱們能夠構造以下(建議子類調用父類的構造方法,參見後續代碼):

 1 class Person(object):
 2     def __init__(self,name,sex):
 3     self.name = name
 4     self.sex = sex
 5 
 6 class Child(Person):                # Child 繼承 Person
 7     def __init__(self,name,sex,mother,father):
 8         self.name = name
 9         self.sex = sex
10         self.mother = mother
11         self.father = father
12 
13 May = Child("May","female","April","June")
14 print(May.name,May.sex,May.mother,May.father)    
Person

 

     若父類構造函數包含不少屬性,子類僅需新增一、2個,會有很多冗餘的代碼,這邊,子類可對父類的構造方法進行調用,參考以下:

 1 class Person(object):
 2     def __init__(self,name,sex):
 3         self.name = name
 4         self.sex = sex
 5 
 6 class Child(Person):                          # Child 繼承 Person
 7     def __init__(self,name,sex,mother,father):
 8         Person.__init__(self,name,sex)        # 子類對父類的構造方法的調用
 9         self.mother = mother
10         self.father = father
11 
12 May = Child("May","female","April","June")
13 print(May.name,May.sex,May.mother,May.father)    

 

  多重繼承

    多重繼承的概念應該比較好理解,好比如今須要新建一個類 baby 繼承 Child , 可繼承父類及父類上層類的屬性及方法,優先使用層類近的方法,代碼參考以下:

 1 class Person(object):
 2     def __init__(self,name,sex):
 3         self.name = name
 4         self.sex = sex
 5         
 6     def print_title(self):
 7         if self.sex == "male":
 8             print("man")
 9         elif self.sex == "female":
10             print("woman")
11             
12 class Child(Person):
13     pass
14 
15 class Baby(Child):
16     pass
17 
18 May = Baby("May","female")        # 繼承上上層父類的屬性
19 print(May.name,May.sex)            
20 May.print_title()                 # 可以使用上上層父類的方法
21 
22 
23 class Child(Person):                
24     def print_title(self):
25         if self.sex == "male":
26             print("boy")
27         elif self.sex == "female":
28             print("girl")
29             
30 class Baby(Child):
31     pass
32             
33 May = Baby("May","female")
34 May.print_title()                # 優先使用上層類的方法
相關文章
相關標籤/搜索