物件導向概念筆記 -- python

先說,我的 OO 是從 JAVA開始接觸的,所以有些哲學也許不太 python...

什麼是 "物件" (object)?

沒什麼,就字面上的意思,很籠統很模糊。以日常生活的經驗來說,物件可以是任何東西,比方說某隻狗,某張桌子,某個人,某個團體... 隨便任何一個東西。以寫程式的角度來說,一個函式、變數都可以是物件。

什麼是 "類別" (class)?

用來描述/定義物件的東西。裡面通常會有屬性與方法兩種內容。屬性是名詞,方法是動詞。比方說我們可以寫個 "人" 這個類別,像是 "姓名","年齡","性別" 這些像名詞的,就是人類別的屬性。而 "說話","睡覺","跑步" 這些有動作的,就是人類別中的方法。

物件導向的特性 -- 繼承,封裝,多型

很重要,很抽象,很高大上,所以寫大字一點,不懂沒關係,會烙話就威猛一百倍... (誤)

========================== 分隔線 ===============================

以下演示 "繼承" 特性

建立 class與繼承

背景

既然手機沒辦法玩 Pokemon,就自己來隨便寫寫吧... (誤)

我建立了三個 class,分別是 Pokemon、mouse、和 frog。其中 Pokemon是父類別,mouse和 frog是子類別

先看父類別 -- Pokemon

Pokemon中有一個屬性和三個方法,屬性的 status 表示 Pokemon的狀態為野生或馴服。三個方法是 tam、bark、和 ability。其中 tam是用來改變 class屬性的,呼叫 tam會要求輸入 owner和 name兩個字串,並修改/增加 class的屬性。

因為每種怪獸的叫聲和能力都不同,所以我寫了bark和 ability的方法名稱,但沒有定義任何內容,而是給子類別的 mouse和 frog去實作。如果寫子類別的人忘記實作這兩個方法,python會吐 NotImplementedError 的錯誤訊息

子類別 -- mouse 和 frog

python的繼承就是在 class的括號中放進父類別的名字。之後子類別就自動擁有一切父類別的屬性與方法。所以,我們就不需要在子類別裡寫 tam方法。不過,bark和 ability是要在此實作。


In [108]:
class Pokemon():
    status="wild"  #初始 status為野生
    def tam(self,owner,name):
        self.owner=owner  #擁有者
        self.name=name    #取名字
        self.status="tamed" #改變 status為馴化
    def bark():
        raise NotImplementedError #留給子類別實作
    def ability():
        raise NotImplementedError #留給子類別實作

In [109]:
class mouse(Pokemon):
    def bark(self):
        print("Pica~ Pica~")
    def ability(self):
        print("I can discharge!")

In [110]:
class frog(Pokemon):
    def bark(self):
        print("Croak! Croak!")
    def ability(self):
        print("I can swim~")

In [111]:
pika=mouse()
pika.tam("Poshih","Pika")
pika.bark()
pika.ability()
print(pika.name)
print(pika.owner)


Pica~ Pica~
I can discharge!
Pika
Poshih

In [132]:
妙蛙=frog()
妙蛙.bark()
print(妙蛙.status) #還沒馴化, 所以是 wild, 也不會有 owner和 name這兩個屬性, 可以試試 print(妙蛙.name)會怎樣


Croak! Croak!
wild

範例 2

人事薪資小程式

屬性: 時薪, 加班時薪 方法: 人事資料, 計算薪資 繼承樹: employee --> labor --> manager


In [125]:
class employee():
    rate=5.
    over=2.*rate
    def person_info(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def salary():
        raise NotImplementedError

In [126]:
class labor(employee):
    rate=10.
    over=2.*rate
    def salary(self,hours):
        if hours <= 8:
            money=self.rate*hours
        else:
            money=self.rate*(8.)+self.over*(hours-8.)
        return money

In [127]:
class manager(labor):
    bonus=100.
    rate=20.
    def salary(self,hours,cases):
        money=super().salary(hours)+(self.bonus*cases)
        return money

In [128]:
p1=labor()
p1.person_info('John',24,'Male')

In [129]:
p1.salary(10.)


Out[129]:
120.0

In [130]:
p2=manager()
p2.person_info('Mary',55,'Female')

In [131]:
p2.salary(10.,3)


Out[131]:
500.0

In [ ]: