# OO終極夢魘(Python)
### 資管惡夢(外系的朋友看好拉)
---
### OO(不是念圈圈是喔喔)
這邊先來個輕鬆的故事
----
### 以下完整版請在Dcard搜尋
[~~還是附上連結好了~~](https://www.dcard.tw/f/yuntech/p/236759775)
Dcard 國立雲林科技大學版
是個拿來給雲科的學生交流興趣、討論課程(簡單來說就是問哪個老師的課程涼)、課程相關資訊與外系零基礎是否可以來修習、以及檢舉雲科在龍潭路出現的猴子
----
[問卦]為甚麼AI技優專班的OO不是必修?
如題,資管新招生的AI專班,課程流程圖裡的OO竟然是選修!!,這樣就少了一樣資管人共同回憶了誒,少了出社會超實用的OO真的是太可惜了
為什麼AI專班不用修OO呢?
----
### 我預想的正常回覆

我的大OO
----
### 我所看到的回覆

敢不敢講出來啦
你的那條XX好短小
----
### 阿看來我們有朋友們不認識OO把她當作匿名了
比如:資O系(這個概念)
那我們來為大家解惑一下OO到底是個啥
---
# 物件導向軟體工程(OO)
物件導向程式設計
##### Object-oriented programming(OOP)
##### Object-oriented analysis and design(OOSE)
----
### 介紹
具有物件概念的程式設計典範,同時也是一種程式開發的抽象方針。
<!-- 它可能包含資料、特性、程式碼與方法。物件則指的是類別(class)的實例。它將物件作為程式的基本單元,將程式和資料封裝其中,以提高軟體的重用性、靈活性和擴充性,物件裡的程式可以存取及經常修改物件相關連的資料。在物件導向程式程式設計裡,電腦程式會被設計成彼此相關的物件 -->
[結構化程式設計 從董哥那裏偷的](http://wiki.plweb.org/Java/Java_slide)
[物件導向程式設計 也是偷來的](http://wiki.plweb.org/Java/Object-Oriented_Programming_in_Java)
----
### 我雖然說了這麼多 但對你來說

----
### 簡單來說
**把真實世界的事物抽象化為物件。**
抽象化? Abstraction?
舉個例子,試著描述何謂電腦?
----
底下是五個人的回答:
A:一種計算設備。
B:由滑鼠、鍵盤、螢幕、主機構成的裝置。
C:可以提供服務、解決問題的物品。
D:一種可以讓你熬夜爆肝的惡魔玩具。
E:可以快速執行指令的東西(?。
----
不管你的答案是什麼,你在腦海裡試著描述的這個動作就叫『抽象化 (Abstraction)』。 一般來說抽象化的越詳細,越能表述你想要描述的物體,但實務上還是要依現實需求去思考抽象化的程度。
----
**好處? Benefits?**
程式的可重複利用性 (Reusability)
程式設計師可以重複的使用母類別(super class)的程式。
軟體原型 (Software Prototyping)
類別的發展可以視為一顆軟體IC,使系統的開發更簡單且有效率。
----
### 總的來說
在控制程式的時候
以物件為單位或個體及概念進行開發
[參考文章](https://www.maxlist.xyz/2021/01/11/python-object/)
----
### 以設計汽車來說


----

----
### 你還記得多少Python呢?(沒有OO的部分)
----
##### 補充一下上次沒講到的 del
del 是Python的一個保留字
使用方法 del 某個物件或變數
```python=
ary=["FKT","Min","Pendy"]#用Arraylist做範例
print(ary)#["FKT","Min","Pendy"]
del ary
print(ary)#NameError: name 'ary' is not defined
```
----
#### 首先用 Class 來定義類別
1. self.working_hour = 0 為定義屬性
2. def work(self): 為定義方法
```python=
class Employee:
def __init__(self):
self.working_hour = 0 #屬性
print("i created")
def work(self): #方法
self.working_hour += 1
print("Working:", self.working_hour)
def __del__(self):
print("Good Bye i disappeared")
andy = Employee() #i created 類的實例化
andy.work() # 呼叫類的方法
print(andy.working_hour) #1 呼叫類的屬性
del andy#Good Bye i disappeared
```
[關於self](https://www.itread01.com/content/1544582523.html)
----
### 常用的物件方法
```python=
__init__ #是定義(創建)物件的事件
__del__ #刪除物件事件
__str__#物件的描述
__doc__ #物件文件
__name__ #類別名稱
__module__ #模組名稱
__cmp__#物件比較
__hash__ #物件雜湊值
```
[各種物件方法](https://www.tutorialspoint.com/python/python_classes_objects.htm)
----
#### 定義物件屬性(三種)
```python=
class ThisTestClass:
getName = 'Max' #方法一:把屬性定義寫在init外面(直接寫在類別底下)
def __init__(self):
self.getNameFromInit = 'Max__init__' #方法二:把屬性定義寫在init內
pass#沒什麼意義 通常是用來提醒自己這邊稍後需要繼續開發
if __name__ == "__main__":
task = ThisTestClass()
task.sendName = "Max_sendName" ##方法三:自己給屬性與參數
print(task.getName)
print(task.getNameFromInit)
print(task.sendName)
```
[關於'__main__'](http://blog.castman.net/%E6%95%99%E5%AD%B8/2018/01/27/python-name-main.html)
----
#### 物件導向有三大基本特性,分別是
1.封裝 (encapsulation)
2.繼承 (inheritance)
3.多型 (polymorphism)
----
### 繼承 (inheritance)
~~簡單來說:繼承就像是生活中,子女繼承父母的財產一樣。~~
範例:首先 Parent 是這次的父親,而 Andy 是繼承 Employee 的孩子
----
```python=
class Parent:
def __init__(self):
self.cut_tree = 3#定義砍樹能力值
class Andy(Parent):#class Andy(Parent),這邊讓 Andy 繼承 Parent物件
def __init__(self, get_gold):
super().__init__()
self.get_gold = get_gold#這邊 super 是呼叫父類別的語法,所以繼承了父親的能力
def getDetials(self):
print('==getDetals==')
print('tree:', self.cut_tree)#繼承後即可使用父親能力
print('gold:', self.get_gold)
if __name__ == "__main__":
andy = Andy(1)
andy.getDetials()
```
----
### 封裝 (encapsulation)
即是將物件內部的資料隱藏起來,只能透過物件本身所提供的介面(interface)取得物件內部屬性或者方法,物件內部的細節資料或者邏輯則隱藏起來,其他物件即無法瞭解此物件的內部細節
>封裝從字面上理解就是包裝的意思
>比方 跑車引擎你不知道她怎麼會發動
>我們只知道要插鑰匙按開關就可以發動,但不了解其中運作的過程,這功能就是封裝。
----
### 多型 (polymorphism)
繼承父類別後的子類別可以設計出不同且獨立的方法
是指說在相同類別中,定義名稱相同,但是參數個數不同,或是參數型態不同的函式
多型(Polymorphism)則包含多載(Overloading)和複寫(Overriding)。
----
### 範例程式
```python=
class Parent:
def work(self):
print('Parent work')
class Andy(Parent):#繼承Parent
def work(self):
print('Andy work')
class Joy(Parent):#繼承Parent
def work(self):
print('Joy work')
w = Parent()
w1 = Andy()
w2 = Joy()
w.work()#Parent work
w1.work()#Andy work
w2.work()#Joy work
```
----
### 私有變數Private Variable
我們在 Class 的變數實例前加上兩個_
Python就會自動認定為Private Variable
----
### 那....有差嗎?
當然有差,差別在這個Variable能不能被其他非該Class存取
我們來個範例
----
```python=
class mainclass:
__privateVariable = 2020;
def __privateMethod(self):
print("I'm inside class mainclass that is this is private method")
def insideclass(self):
print("Private Variable: ",mainclass.__privateVariable)
self.__privateMethod()
foo = mainclass()
foo.insideclass()
print(foo.__privateVariable)#AttributeError: 'mainclass' object has no attribute '__privateVariable
```
---
### simple challenge
設計出簡單的物件導向程式,需先建構Car父類別,並且宣告物件的同時要給予(承載人數),且在定義兩個子類別Taxi跟Bus並在這兩個子類別內定義回傳承載人數方法getBearer()
範例輸出:
計程車承載人數 5
公車承載人數 20
----
### 補充介面 Interface
由於Python本身沒有設計Interface這個概念
於是乎我們使用Zope 這個模組
----
```pythom=
from zope.interface import Interface
from zope.interface.declarations import implementer
# 定義介面
class MyMiss(Interface):
def imissyouatlost(self,miss):
"""Say i miss you at lost to miss"""
@implementer(MyMiss) # 施加介面
class Miss:
def imissyouatlost(self,somebody):
"""Say i miss you at lost to somebody"""
return "i miss you at lost, %s!" % somebody
if __name__ == '__main__':
z = Miss()
hi = z.imissyouatlost('Zy')
print(hi)
```
----
##### 延伸閱讀
[Class / Static /Abstract Method](https://www.maxlist.xyz/2019/12/12/python-oop/)
[Python OOP 另類寫法dataclass module](https://towardsdatascience.com/9-reasons-why-you-should-start-using-python-dataclasses-98271adadc66)
[在Python使用與自定義Interface 使用Zope](https://www.cnblogs.com/imyalost/p/8598343.html)
---
### 感謝聆聽
{"metaMigratedAt":"2023-06-16T11:11:18.448Z","metaMigratedFrom":"YAML","title":"OO終極夢魘(Python)","breaks":true,"contributors":"[{\"id\":\"4c8f8799-9dcd-430b-b7bc-8a5156d39d0b\",\"add\":9419,\"del\":3080}]"}