# OOP
資訊之芽北區py班
yjrubixcube
---
## 上一節課在幹嘛?
- 什麼是 class
- method, attribute
----
## 這一節課又要幹嘛?
- OOP
- 繼承 inheritence
- 多型 polymorphism
- 封裝 encapsulation
---
## 什麼是OOP
![](https://i.imgur.com/rdnZdLG.jpg)
----
### ChatGPT說
OOP stands for **Object-Oriented Programming**, which is a programming paradigm that focuses on creating objects that encapsulate data and behavior. In Python, OOP is implemented through classes and objects.
----
- 把東西包成物件
- 方便重複使用、管理
- python 中使用 class/object
---
## 繼承 Inheritance
----
- 課本學到的 [記承](https://fanti.dugushici.com/ancient_proses/70534)
- 民法裡面的 [繼承](https://law.moj.gov.tw/LawClass/LawParaDeatil.aspx?pcode=B0000001&bp=126)
- 在現有 class 上做延伸
- 降低程式的重複性
----
沒用繼承
![](https://i.imgur.com/HIv068m.png)
----
用繼承
![](https://i.imgur.com/AD72E3z.png)
也可以用
`Animal.__init__(self, name)`
----
```python
c = Cat("Hello Kitty", "vase")
d = Dog("狗勾", "啊啊啊")
c.reqires()
c.knock_over()
d.reqires()
d.make_sound()
# Hello Kitty reqires food and water
# Hello Kitty knocked over the vase
# 狗勾 reqires food and water
# 狗勾 says 啊啊啊
```
----
也可以一次繼承很多個 class
![](https://i.imgur.com/5eqEISY.png)
`super()` 是傳進去的第一個class
----
也可以繼承好幾層
![](https://i.imgur.com/vXwdQcZ.png)
----
練習
寫出兩個繼承`Dog`的class `Dachshund, PitBull`。
`Dachshund` 有額外的屬性`length`
`PitBull`有額外的屬性`strength`
並建立以下兩個instance
|type|name|sound|length|strength|
|-|-|-|-|-|
|Dachshund|Sausage|Woof!|30|x|
|Pitbull|Bull|Woof!|x|100|
---
## 多型 Polymorphism
![](https://i.imgur.com/zA4ny2B.jpg)
----
- 讓不同物件執行相同名稱的方法
- 子類別的方法會蓋過原類別的方法
----
![](https://i.imgur.com/Y76739b.png)
----
```python
b = bird()
d = duck()
c = chicken()
say_something(b) # Moo!
say_something(d) # 西呱
say_something(c) # 嘰嘰喳喳
```
因為 `bird, duck, chicken` 都有 `speak` 方法
所以都可以在`say_something`裡面呼叫`.speak()`
----
如果我的子class沒有`.speak()`?
```python
class Ditto(bird):
def __init__(self):
super().__init__()
cow = Ditto()
say_something(cow)
```
`Moo!`
<!-- .element: class="fragment" data-fragment-index="1" -->
用 `bird` 裡面的
<!-- .element: class="fragment" data-fragment-index="2" -->
----
練習
改寫上面的class,使得我們使用`print(obj)`的時候會印出該obj對應的字串(`Moo!, 西呱, 嘰嘰喳喳`)
hint: 可以試試看上節課講的Magic method?
---
## 封裝 Encapsulation
:pill:
----
- 把資料藏起來
- 只能透過特定方法存取/修改
----
![](https://i.imgur.com/uUC2GjK.png)
前面雙底線代表 private attribute/method
只能在class裡面存取
----
```python
b = Bank("合作金庫", 8787)
b.print_info()
# 合作金庫
# 8787
```
----
```python
b.name += "台大分店"
b.print_info()
# 合作金庫台大分店
# 8787
b.__total += 10000
# AttributeError: 'Bank' object has no attribute '__total'
b.__total = 10000
b.print_info()
# 合作金庫台大分店
# 8787
```
----
如果我真的想改 private 怎麼辦
```python
b.more_money(10000)
b.print_info()
# 合作金庫台大分店
# 18787
```
----
練習
請加強合作金庫的安保,讓外人也不能直接改name,只能透過`obj.change_name(name)` 來更改
---
## Q&A
{"metaMigratedAt":"2023-06-18T02:59:05.934Z","metaMigratedFrom":"YAML","title":"OOP","breaks":true,"contributors":"[{\"id\":\"54bbdba3-ffbf-423a-b026-751cb8a77149\",\"add\":4470,\"del\":1661}]"}