繼承

  • 繼承也是面向物件程式設計三大特性之一
  • 繼承是類與類的一種關係
  • 定義一個新的 class 時,可以從某個現有的 class 繼承
  • 新的 class 類就叫子類(Subclass)
  • 被繼承的類一般稱為父類、基類、超類
  • 通俗理解:子類與父類的關係,即爸爸與兒子,爸爸有了個兒子,兒子繼承爸爸的屬性和方法,爸爸的爸爸就是爺爺...以此類推

繼承的實際栗子

  • 貓、狗都是動物,所以動物是父類,貓、狗是動物的子類
  • 小菠蘿、大菠蘿都是人類,所以人類是父類,小菠蘿、大菠蘿是人類的子類
  • 動物、人類都是生物,所以生物是父類,動物、人類是生物的子類
  • 那麼一般稱生物類是貓、狗、小菠蘿、大菠蘿的超類、祖父類

繼承的好處

  • 實現程式碼的重用,相同的程式碼不需要重複編寫
  • 子類擁有父類的所有屬性、方法,提高了程式碼的可擴充套件性和重用性
  • 在子類繼承父類的同時,也可以重新定義某些屬性,並重寫某些方法,即覆蓋父類的屬性、方法,變成子類獨有的屬性、方法
  • 子類也可以新增新的屬性、方法

繼承的使用場景

  • 假如我需要定義幾個類,而類與類之間有一些公共的屬性和方法
  • 可以把公共的屬性和方法提取作為父類(基類)的屬性、方法,而特殊的屬性、方法則在本類中定義
  • 比如貓、狗都有吃喝拉撒四種行為,這些就是公共方法;但只有貓會喵喵叫,只有狗會汪汪叫,這些就是特殊方法

具體可以看下面的【不使用繼承、使用繼承的區別】

繼承有幾種?

  1. 單繼承
  2. 多繼承

Python 中繼承的簡單語法

  1. class Parent:
  2. pass
  3.  
  4. class Child(Parent):
  5. pass

有個重點

所有類的都有一個共同父類,就是 object,預設會繼承它,寫或不寫都一樣

  1. class Parent:
  2. pass
  3.  
  4. class Parent(object):
  5. pass

不使用繼承、使用繼承的區別

需求背景

有一個動物類、狗類、貓類

  • 動物類有吃、喝、跑方法
  • 狗類有吃、喝、跑、汪汪叫方法
  • 貓類有吃、喝、跑、喵喵叫方法

不使用繼承

類圖

需求分析

  • 每個類都擁有自己的方法
  • 他們都擁有吃、喝、拉方法,且功能一樣

實際程式碼

  1. # 不使用繼承
  2. class Animal:
  3. def eat(self):
  4. print("吃東西...")
  5.  
  6. def drink(self):
  7. print("喝水...")
  8.  
  9. def run(self):
  10. print("跑步...")
  11.  
  12. class Cat:
  13. def eat(self):
  14. print("吃東西...")
  15.  
  16. def drink(self):
  17. print("喝水...")
  18.  
  19. def run(self):
  20. print("跑步...")
  21.  
  22. def miao(self):
  23. print("喵喵叫...")
  24.  
  25. class Dog:
  26. def eat(self):
  27. print("吃東西...")
  28.  
  29. def drink(self):
  30. print("喝水...")
  31.  
  32. def run(self):
  33. print("跑步...")
  34.  
  35. def wang(self):
  36. print("汪汪叫...")

這樣寫有什麼問題?

  • 三個類,需要重複寫三次吃、喝、跑的方法
  • 假設此時需要修改 吃 方法的程式碼,那麼還得同步修改三個類的 吃 方法,屬於不必要的重複性工作
  • 使用繼承可以大大減少開發工作量

使用繼承

類圖

從類圖就能看到,使用繼承就變得簡單多了

需求分析

  • 提取三個類的公共方法,吃、喝、跑,然後抽象成動物類
  • 所以動物類是一個父類,狗類、貓類繼承它

實際程式碼

  1. # 使用繼承
  2. class Animal:
  3. def eat(self):
  4. print("吃東西...")
  5.  
  6. def drink(self):
  7. print("喝水...")
  8.  
  9. def run(self):
  10. print("跑步...")
  11.  
  12. class Cat(Animal):
  13. def miao(self):
  14. print("喵喵叫...")
  15.  
  16. class Dog(Animal):
  17. def wang(self):
  18. print("汪汪叫...")

優勢

  • 子類繼承父類,可以直接享受父類已經封裝好的方法,不再需要自己開發一次
  • 子類可以根據自身的需要,封裝子類獨有的屬性、方法,比如貓類的喵喵叫,狗類的汪汪叫

專業術語總結

  • Dog 類是 Animale 類的子類,Animal 類是 Dog 類的父類,Dog 類從 Animal 類繼承
  • Dog 類是 Animale 類的派生類,Animal 類是 Dog 類的基類,Dog 類從 Animal 類派生

繼承的傳遞性

什麼是傳遞性

通俗來講

  • C 類從 B 類繼承,B 類又從 A 類繼承
  • 那麼 C 類會擁有 A、B 類的所有屬性和方法

官方來講

子類擁有父類以及父類的父類,以及所有父類的父類的父類...中封裝的所有屬性、方法

實際栗子

  • 還是拿上面的動物類、狗類、貓類繼續展開講
  • 假設此時有一個新的類叫柴犬類,繼承於狗類,有獨有的方法搖尾巴

類圖

實際程式碼

  1. class Animal:
  2. def eat(self):
  3. print("吃東西...")
  4.  
  5. def drink(self):
  6. print("喝水...")
  7.  
  8. def run(self):
  9. print("跑步...")
  10.  
  11. class Cat(Animal):
  12. def miao(self):
  13. print("喵喵叫...")
  14.  
  15. class Dog(Animal):
  16. def wang(self):
  17. print("汪汪叫...")
  18.  
  19. class Chai(Dog):
  20. def shake(self):
  21. print("小柴柴搖尾巴...")
  22.  
  23. chai = Chai()
  24. # 呼叫 父類的父類 的方法
  25. chai.eat()
  26. # 呼叫 父類 的方法
  27. chai.wang()
  28. # 呼叫 自己獨有 的方法
  29. chai.shake()
  30.  
  31. # 輸出結果
  32. 吃東西...
  33. 汪汪叫...
  34. 小柴柴搖尾巴...
  • Chai 類擁有 Dog 類、Animal 類所有屬性、方法
  • 但它不會擁有 Cat 類的屬性、方法,因為他們沒有繼承關係

繼承和抽象

抽象即抽取類似或者說比較像的部分

小栗子

  • 從小菠蘿、小韻韻兩個物件中,抽取公共部分抽象成父類
  • 再從人,豬,狗這三個類,抽取公共部分抽象成父類

繼承的重點

  • 是基於抽象的結果,通過程式語言去實現它
  • 先經歷抽象這個過程,才能通過繼承的方式去表達出抽象的結構
  • 抽象只是分析和設計的過程中,一個動作或者說一個技巧,通過抽象得到一個類

程式碼栗子

  1. class Animal:
  2. def __init__(self, name, age, sex):
  3. self.__name = name
  4. self.__age = age
  5. self.__sex = sex
  6.  
  7. # 提取的公共方法
  8. def eat(self):
  9. print(f"{self.__name} 正在吃飯....")
  10.  
  11. @property
  12. def name(self):
  13. return self.__name
  14.  
  15. class Person(Animal):
  16. def walk(self):
  17. print(f"{self.name} 兩條腿正在走路")
  18.  
  19. class Pig(Animal):
  20. def kill(self):
  21. print(f"{self.name} 豬正在去屠宰場ing...")
  22.  
  23. class Dog(Animal):
  24. def wang(self):
  25. print(f"{self.name} 汪汪叫ing...")
  26.  
  27. person = Person("小菠蘿", 25, "Male")
  28. pig = Pig("麥兜", 4, "公")
  29. dog = Dog("柴犬", 3, "母")
  30.  
  31. # 呼叫父類的公共方法
  32. person.eat()
  33. pig.eat()
  34. dog.eat()
  35.  
  36. # 呼叫子類獨有的方法
  37. person.walk()
  38. pig.kill()
  39. dog.wang()
  40.  
  41. # 輸出結果
  42. 小菠蘿 正在吃飯....
  43. 麥兜 正在吃飯....
  44. 柴犬 正在吃飯....
  45.  
  46. 小菠蘿 兩條腿正在走路
  47. 麥兜 豬正在去屠宰場ing...
  48. 柴犬 汪汪叫ing...