為自己Coding
為自己Coding

YO~~ 剛跨入AI人工智慧領域的小小工程師, 熱愛自學, 熱愛分享, 下班後的我想為自己Coding, 積極撰寫教學文, 想將自學的程式知識分享給大家, 不斷追求進步的自己, 希望有一天能回饋社會,幫助需要幫助的人, 如果您有什麼很酷的想法,也覺得我還行,歡迎您找我合作~~ IG: https://www.instagram.com/coding_4_me/

給自己的Python小筆記: 物件導向設計OOP教學

哈囉,今天來跟大家介紹一下物件導向設計OOP,相信大家學程式就算沒用到,也都一定會聽到OOP這個概念,在學習程式的過程中,你可能會覺得物件導向這個名詞有聽過,也知道它有三大特性,但好像不一定要用到,我們今天就來一起看看物件導向設計是做什麼的,用了可以幹麻

1. 物件導向設計 與 程序導向設計 差異

a. 程序導向設計: 簡單來說,以函式當程式的基本單元,就是在撰寫專案程式的過程中,我只使用函式(function(def))來寫下我的功能,並用排序的方式來讓程式知道依序跑哪個function,然後通過將比較大的函式切割成多個小函式,來降低程式維護的複雜度。b. 物件導向設計: 簡單來說,以物件當成式的基本單元,就是在撰寫專案程式的過程中,我使用了Class類來創立各種物件,並透過物件間互相傳遞與接收訊息,達成專案的目的。

2. 為什麼要使用物件導向設計:

啊我程序導向設計寫得好好的,幹嘛要會物件導向設計

a. 更容易閱讀: 每個類(Class)都清楚定義了功能 ,讓使用者可以輕鬆閱讀與理解程式邏輯b. 更好維護與新功能添加: 維護上可以清楚針對需要的類(Class)或物件進行修改,也更好擴充新的功能到指定的類(Class)

3. 物件導向 三大特性: 繼承(inheritance)、封裝(encapsulation)、多型(polymorphism)

a.繼承(inheritance) : 簡單來說就是子類別(subclass)繼承一個父類別(class),小朋友繼承了父親有的特性,除非屬性被隱藏起來,設定為private,不然都會被繼承,也就是public屬性都會被繼承
b.封裝(encapsulation): 簡單來說,封裝其實就是將程式包成一個一個的類(class)和函式(function),使用者不需要注意裡面的細節,只要會使用接口就好,像是類.函式名稱()
c.多型(polymorphism): 簡單來說就是大家都繼承了相同的類別,也呼叫相同的函式,但結果卻不同

4. Class 繼承(inheritance)

簡單來說就是子類別(subclass)繼承一個父類別(class),小朋友繼承了父親有的特性,除非屬性被隱藏起來,設定為private,不然都會被繼承,也就是public屬性都會被繼承

a. 繼承的使用方法:
Class(類別)名稱後面的()中,寫下父類別的類別名稱,下面的程式舉例幾種繼承的方法,每個方法中都實作出子類別可以繼承父類別的公開的屬性(實體與類別屬性),也可以自己新增(覆寫)一些屬於子類別才有的屬性

i.第一種方法: 使用Dad_Ken.__init__(self)來繼承,(優點)明確知道指向哪個父類別, (缺點)會有一個麻煩的地方只要繼承的類別改變,就要更動
ii .第二與第三種方法: 使用super(Child_Jen, self).__init__() 或 super().__init__(),他們都改善了第一種方法的缺點,使用這兩種方法還有一個重要原因就是Dependency Injection(依賴注入),那是什麼?簡單來說,就是物件在create時會產生自己需要的dependency, 而依賴注入,就是需要的dependency由client端注入。
iii.檢查繼承關係的方法: issubclass(子類別,父類別),issubclass(Child_Jen, Dad_Ken),如果是的話就會返回True
iiii. 私有屬性: 原則上父類別的私有屬性不會被繼承,除非父類別有設定其他公開的方式取得私有屬性,舉例:__child透過child()獲得
## 父類別
class Dad_Ken: 
 first_name = ‘Hsu’
 ## 私有屬性
 __child = 1
 def __init__(self):
 self.address = ‘any Town any Street’
 self.blood = ‘o’
 self.phone_number = ‘0931xx’
 ## 私有屬性
 Dad_Ken.__child+=1
 
 @property
 def cook(self):
 return “I can cook”
 
 ## 私有屬性取得方式
 @classmethod
 def child(cls):
 return cls.__child
## 子類別 繼承父類別
## 第一種方法
class Child_Jen(Dad_Ken):
 def __init__(self):
 Dad_Ken.__init__(self)
 
 @property
 def swim(self):
 return “I can swim, but my father can’t”
## 第一種方法
Jen = Child_Jen()
print(Jen.first_name) # Hsu
print(Jen.address) #any Town any Street
print(Jen.blood) #o
print(Jen.cook) #I can cook
print(Jen.swim) #I can swim, but my father can’t
print(Jen.child()) #2 ##私有屬性取得
Ken = Dad_Ken()
# print(Ken.swim) # AttributeError: ‘Dad_Ken’ object has no attribute ‘swim’
print(Ken.child()) #3 ##私有屬性取得
## 繼承檢查
print(issubclass(Dad_Ken, Child_Jen)) ## False
print(issubclass(Child_Jen, Dad_Ken))## True
##第二種方法
class Child_Una(Dad_Ken):
 def __init__(self):
 super(Child_Una, self).__init__()
 
 @property
 def basketball(self):
 return “I love to plaay basketball”
Una = Child_Una()
print(Una.first_name) #Hsu
print(Una.basketball) # I love to plaay basketball
print(Una.cook) # I can cook
print(Una.child()) #4
## 第三種方法
class Child_Jack(Dad_Ken):
 def __init__(self):
 super().__init__()
 @property
 def run():
 return “I can run fast”
Jack = Child_Jack()
print(Jack.first_name) #Hsu
# print(Jack.basketball) # AttributeError: ‘Child_Jack’ object has no attribute ‘basketball’
print(Jack.cook) #I can cook
print(Jack.child()) #5

5. 多重繼承

a.多重繼承使用方法:
i. Class(類別)名稱後面的()中,寫下所有父類別的類別名稱,格式: 子類別(父類別1, 父類別2)、subclass(superclass1,superclass2)

ii. 如果所有的父類別擁有相同的屬性,以最左邊的父類別繼承的為優先

iii.當兩個父類別都有__init__時,只會繼承最左邊父類別的__init__底下屬性,但如果有不同的function名稱,就可以都繼承,像是:

print(Tom.blood) ## AttributeError: ‘Child_Tom’ object has no attribute ‘blood’ 當兩個父類別都有__init__時,只會繼承最左邊父類別的__init__底下屬性 print(Tom.cook) #I can cookprint(Tom.cure) #I can cure myself

舉例:

## 父類別1
class Dad_Ken: 
 first_name = ‘Hsu’
 ## 私有屬性
 __child = 1
 def __init__(self):
 self.address = ‘any Town any Street’
 self.blood = ‘o’
 self.phone_number = ‘0931xx’
 ## 私有屬性
 Dad_Ken.__child+=1
 
 @property
 def cook(self):
 return “I can cook”
 
 ## 私有屬性取得方式
 @classmethod
 def child(cls):
 return cls.__child
 
## 父類別2
class Mon_Linda():
  first_name = ‘Zin’
  def __init__(self):
   self.mom = ‘Linda’
  @property
  def cure(self):
   return “I can cure myself”
## 子類別
class Child_Tom(Mon_Linda,Dad_Ken):
  def __init__(self):
    super().__init__()
Tom = Child_Tom()
print(Tom.first_name) ## Zin 以左邊的父類別為優先繼承
print(Tom.blood) ## AttributeError: ‘Child_Tom’ object has no attribute ‘blood’ 當兩個父類別都有__init__時,只會繼承最左邊父類別的__init__底下屬性
print(Tom.mom) #Linda
print(Tom.cook) #I can cook
print(Tom.cure) #I can cure myself

6. 多型(polymorphism)

簡單來說就是大家都繼承了相同的類別,也呼叫相同的函式,但結果卻不同
舉例: 父類別(Dad_Ken)有個屬性cook, 兩個子類別(Tonny and Tim)都繼承了這個屬性,但呼叫屬性後,產生的結果不同,說明了Python會根據指定的Class(類別),來決定如何實作方法
## 父類別
class Dad_Ken:
def __init__(self):
     self.name = ‘Dad Ken’
def __str__(self):
     return str(self.name)
def cook(self):
     print(‘Cook by ‘ + self.__str__() )
## 子類別 1
class Child_Tonny(Dad_Ken):
  def __init__(self):
     super().__init__()
     self.name = ‘Tonny’
def __str__(self):
     return str(self.name)
 
## 子類別 2
class Child_Tim(Dad_Ken):
  def __init__(self):
     super().__init__()
     self.name = ‘Tim’
def __str__(self):
     return str(self.name)
print(Dad_Ken().cook()) # Cook by Dad Ken
print(Child_Tonny().cook()) # Cook by Tonny
print(Child_Tim().cook()) #Cook by Tim

7.封裝

簡單來說,封裝其實就是將程式包成一個一個的類(class)和函式(function),使用者不需要注意裡面的細節,只要會使用接口就好,像是類.函式名稱()

1. Public: 使用者只要知道類裡面有什麼函式可以使用,即可輕鬆使用,不需要知道太多程式過程細節
2. Private: 有些屬性不想讓外界的人直接閱讀的屬性 a. 目的: 很簡單,就是過往我們在Class裡面的屬性都是門戶洞開的,任何人都能輕易看到裡面的內容,但是我們有時候想要一點隱私(private),就是不想被別人輕鬆看見,所以我們要用封裝的方法,將屬性隱藏起來,但我們自己要讀,所以我們要用別的方式讀取這些屬性內容 b. 怎麼做: 我們只要將想要隱藏的屬性是別字加上__(兩個底線)就能輕鬆實現
class House:
 
 def __init__(self, address, name, phone_number):
 self.__address = address
 self.__name = name
 self.phone_number = phone_number
 self.member = 0
little_turtle_home = House(‘any Town any Street’, ‘Turtle’, ‘09xx’)
print(little_turtle_home.phone_number) ## 沒封裝成私有: 09xx
print(little_turtle_home.__address) ## 有封裝成私有: AttributeError: ‘House’ object has no attribute ‘address’



希望這次也對大家有很多的幫助!!

Reference:

https://medium.com/@zxuanhong/dependency-injection是什麼-ae83f7f87d6d
https://codertw.com/程式語言/115956/
https://medium.com/tsungs-blog/python-初探物件導向-59c97981c7d6

CC BY-NC-ND 2.0 版权声明

喜欢我的文章吗?
别忘了给点支持与赞赏,让我知道创作的路上有你陪伴。

加载中…

发布评论