在學過變數、運算子、條件判斷、迴圈以及函式之後,我們已經能寫出有邏輯、能重複利用的程式。但隨著功能越來越多,光靠函式和變數來組織程式碼,仍然容易變得凌亂。
物件導向(OOP, Object-Oriented Programming) 就是為了解決這個問題而設計的一種程式設計方式。它的核心精神是:
用生活來比喻:
今天會帶你掌握 OOP 的第一步:
__init__
初始化物件。self
的意義。透過這些基礎,你會發現程式不只是「一堆函式」,而是能以更貼近現實世界的方式來建模,讓結構清楚、可讀性更高,並且更容易擴充。
到目前為止,我們的程式都是「一堆函式」和「一些變數」。
可是當功能多起來時,會變得很難管理。
物件導向(OOP) 就是幫我們整理程式碼的一種方法。
你可以把它想像成:「先有一份藍圖,再照藍圖蓋出很多房子」。
self
:方法裡的「這一個自己」__init__
:建構子,物件剛出生時就會自動跑一次,負責初始化一句話:類別是規格,物件是產品。
class person:
def __init__(self, name, age): # 物件建立時會自動呼叫
self.name = name
self.age = age
def say_hi(self):
print(f"嗨!我是 {self.name},我 {self.age} 歲。")
Cool = person("JR", 25) # 建立物件
Cool.say_hi() # 呼叫方法
Python 自動把 mimi
傳給 self
,所以你呼叫 mimi.say_hi()
時不用自己寫 self
。
class Pet:
species = "動物" # 類別屬性
def __init__(self, name):
self.name = name # 實例屬性
a = Pet("小花")
b = Pet("小黑")
print(a.species, b.species) # 動物 動物
Pet.species = "寵物"
print(a.species, b.species) # 寵物 寵物
類別屬性大家共用,實例屬性各自不同。
-- 類別屬性就像「大家共用的一份規則」,所有物件都會看到同一個值;
-- 實例屬性則像「每個人專屬的身份證」,各自獨立、互不影響。
注意:如果你在某個物件上直接改同名屬性,其實是「多加了一個新的實例屬性」。
class Person:
def __init__(self, name, age, id_number):
self.name = name # 公開
self._age = age # 建議保護,不要隨便改
self.__id = id_number # 私有(會被名稱修飾)
Python 的屬性存取其實靠「慣例」:單底線 _ 代表不建議外部直接用,雙底線 __ 則會觸發名稱修飾避免衝突,但仍能繞過存取,並非真正私有。
Python 沒有真的「私有」,只是透過「名稱修飾」讓你不小心動不到。
有些方法名字長得很奇怪,像是 __str__
。
這些叫 特殊方法(magic method),會在特定情況下自動被呼叫。
class Pet:
def __init__(self, name):
self.name = name
def __str__(self):
return f"這是一隻叫 {self.name} 的寵物"
print(Pet("阿毛")) # 這是一隻叫 阿毛 的寵物
在 Python 的 class
中,常見有 三種方法:
class Tool:
def instance_method(self):
print(f"跟著物件 {self} 走")
t = Tool()
t.instance_method() # 正常呼叫
Tool.instance_method(t) # 也可這樣呼叫,但少用
self
,代表「物件本身」。class Tool:
kind = "工具"
@classmethod
def class_method(cls):
print(f"跟著類別 {cls.__name__} 走,種類是 {cls.kind}")
Tool.class_method() # 類別呼叫
t = Tool()
t.class_method() # 物件呼叫,但語意較弱
cls
,代表「類別本身」。class Tool:
@staticmethod
def static_method(x, y):
print(f"完全獨立:{x + y}")
Tool.static_method(3, 5) # 類別呼叫
t = Tool()
t.static_method(3, 5) # 物件呼叫
self
或 cls
,就是單純的函式。這些會在 Day 7 詳細談。
class Student:
def __init__(self, name, score):
self.name, self.score = name, score
class Classroom:
def __init__(self):
self.students = []
def add(self, student):
self.students.append(student)
def average(self):
return sum(s.score for s in self.students) / len(self.students)
s1 = Student("Jr", 80)
s2 = Student("Sam", 90)
room = Classroom()
room.add(s1)
room.add(s2)
print("平均:", room.average())
物件可以互相合作,這就是 OOP 真正的威力。