← 返回大綱
第八章

物件導向
程式設計

Object-Oriented Programming

概念

什麼是物件導向(OOP)?

把資料(屬性)和行為(方法)包裝在一起,稱為「物件」。

現實世界

  • 一隻貓有:名字、年齡、顏色(屬性)
  • 貓會:叫、吃飯、睡覺(行為/方法)

程式世界

  • class(類別):設計圖/模板
  • object(物件):根據設計圖建出的實體
  • 每個物件都有自己的屬性值
比喻

class Cat 是「貓的設計圖」,my_cat = Cat("咪咪") 是根據設計圖建出的「一隻叫咪咪的貓」。

class

定義類別 class

class Cat:
    def __init__(self, name, age):  # 建構函式
        self.name = name   # 屬性
        self.age = age

    def meow(self):         # 方法
        print(f"{self.name}:喵!")

    def info(self):
        print(f"{self.name},{self.age} 歲")

# 建立物件
cat1 = Cat("咪咪", 3)
cat2 = Cat("小花", 5)

cat1.meow()   # 咪咪:喵!
cat2.info()   # 小花,5 歲
print(cat1.name)  # 咪咪
class

屬性與方法

class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        self.balance += amount
        print(f"存入 {amount},餘額 {self.balance}")

    def withdraw(self, amount):
        if amount > self.balance:
            print("餘額不足!")
        else:
            self.balance -= amount
            print(f"提款 {amount},餘額 {self.balance}")

acc = BankAccount("Ian", 1000)
acc.deposit(500)    # 存入 500,餘額 1500
acc.withdraw(200)   # 提款 200,餘額 1300
繼承

繼承 (Inheritance)

子類別繼承父類別的屬性和方法,再加上自己特有的部分:

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        print(f"{self.name} 說了些什麼...")

class Dog(Animal):          # Dog 繼承 Animal
    def speak(self):        # 覆寫父類別的方法
        print(f"{self.name}:汪!")

class Cat(Animal):
    def speak(self):
        print(f"{self.name}:喵!")

dog = Dog("小黑")
cat = Cat("咪咪")
dog.speak()   # 小黑:汪!
cat.speak()   # 咪咪:喵!
封裝

封裝與私有屬性

class Person:
    def __init__(self, name, age):
        self.name = name          # 公開屬性
        self.__age = age          # 私有屬性(雙底線開頭)

    def get_age(self):            # 透過方法讀取私有屬性
        return self.__age

    def set_age(self, age):       # 透過方法修改(可加驗證)
        if age >= 0:
            self.__age = age

p = Person("Ian", 18)
print(p.name)           # Ian
print(p.get_age())      # 18
# print(p.__age)        # 錯誤!無法直接存取私有屬性
特殊方法

特殊方法 (Magic Methods)

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):           # print() 時呼叫
        return f"({self.x}, {self.y})"

    def __add__(self, other):    # + 運算子
        return Vector(self.x + other.x, self.y + other.y)

    def __len__(self):           # len() 時呼叫
        return int((self.x**2 + self.y**2) ** 0.5)

v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1)           # (1, 2)
print(v1 + v2)      # (4, 6)
print(len(v2))      # 5
實作練習

動手試試看

# 建立一個學生管理系統
class Student:
    def __init__(self, name, grade):
        self.name = name
        self.scores = []
        self.grade = grade

    def add_score(self, subject, score):
        self.scores.append({"subject": subject, "score": score})

    def average(self):
        if not self.scores:
            return 0
        return sum(s["score"] for s in self.scores) / len(self.scores)

    def __str__(self):
        return f"{self.name}({self.grade})平均 {self.average():.1f} 分"

s = Student("Ian", "高一")
s.add_score("數學", 95)
s.add_score("英文", 88)
print(s)  # Ian(高一)平均 91.5 分

第八章完成!

學會了 class、__init__、繼承、封裝與特殊方法。