Home
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try a Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

4

Local AI

--

Uedu Code

--

Taipei AQI 46 · Taichung AQI 76 · Tainan AQI 67 · Kaohsiung AQI 64
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 22

物件導向簡介

類別、實例、self、類別變數與繼承
Interaction實作 30 minute(s)

Learning Objectives

  • 物件導向簡介:物件、類別、實例,以及封裝、繼承、多型
  • 物件導向相關名詞:類別變數、實例變數、方法、方法覆寫
  • 定義與使用 Python 類別:class、__init__ 與 self
  • 用繼承建立子類別,並覆寫父類別的方法

物件:資料加上會做的事

物件(object)是一種自訂的資料結構,裡面有資料(變數,稱為屬性)以及程式碼(函數,稱為方法), 可以想成「內含程式碼的資料結構」。每個物件代表一個具體、獨立的東西,它的方法定義它能做什麼、如何和其他東西互動。

你早就在用物件了:值為 7 的整數是一個物件,它有「加法」的方法;值為 8 的整數是另一個物件。 7 和 8 都屬於 Python 的整數類別(int),各自是這個類別的實例(instance)。

類別像設計圖,實例是照設計圖做出來的東西。同一張設計圖可以做出很多個,每一個有自己的資料。

物件導向的三個特性:

特性 意思
封裝(Encapsulation) 把資料與操作資料的方法包在一起,避免外部任意修改內部狀態,保持資料的一致性
繼承(Inheritance) 從已存在的類別定義新的類別,沿用父類別的屬性與方法
多型(Polymorphism) 同一個介面(同名的方法),不同類別各有自己的做法

定義類別:把變數與函數包在一起

class 類別名稱: 底下縮排的內容就是類別本體。Python 會先執行一次類別本體(框架顯示 class SmartPhone),建立一個類別物件。之後用「類別名稱.屬性」取用裡面的變數與函數。

__init__ 與 self:每個實例有自己的資料

__init__() 是特殊方法,稱為建構子(constructor)或初始化方法:建立實例時 Python 會自動呼叫它。方法的第一個參數是 self,代表「這個物件本身」,呼叫時 Python 會自動傳入。看右邊:myphone 與 yourphone 是兩個不同的實例,各有自己的 name 與 sn。

Lab:Course 類別

這是 Lab 的 baseclass.py:建構子存入課程名稱與時數,兩個方法一個負責印出、一個傳回名稱。注意 display_course() 自己 print,show_course() 則用 return 把值交回給呼叫者。

物件導向名詞整理

名詞 說明
類別(class) 使用者自訂的物件原型,定義這類物件有哪些屬性
物件(object)/實例(instance) 由類別產生的單一物件;例如 c1 是 Course 類別的一個實例
實例化(instantiation) 建立類別的實例:Course('Python', 18)
資料成員(data member) 類別變數或實例變數,儲存共用資料或個別物件的資料
實例變數(instance variable) 在方法裡用 self.名稱 建立,只屬於該實例
類別變數(class variable) 定義在類別內、方法外,所有實例共用一份
方法(method) 定義在類別裡的函數,第一個參數是 self;用「物件.方法()」呼叫
方法覆寫(method overriding) 子類別重新定義父類別的同名方法
運算子重載(operator overloading) 讓運算子對自訂類別有不同功能,例如定義 __add__ 讓 + 可以用

函數重載(同名函數依引數個數或型別有不同行為)在 Python 並不支援,因為 Python 不宣告變數型別;通常改用預設引數來達成類似效果。

類別變數與實例變數

emp_count 定義在類別內、方法外,是類別變數,所有員工共用一份;self.name、self.salary 是實例變數,每位員工各一份。看右邊 Employee 類別物件裡的 emp_count,每建立一位員工就加 1。

互動練習:屬性查找的順序

建立幾個 Dog 實例,再試試 d1.species 與 d1.species = "wolf"。查找屬性時先找實例自己,找不到才往類別找;對實例指派同名屬性,只會在那個實例身上新增實例變數,類別的值不變。

想一想:類別與實例

1.

下面的程式會印出什麼?

class C:
    count = 0
    def __init__(self):
        C.count += 1

a = C()
b = C()
print(C.count, a.count)
2.

下面的程式會印出什麼?

class Dog:
    species = "canine"

d1 = Dog()
d2 = Dog()
d1.species = "wolf"
print(d1.species, d2.species, Dog.species)
3.

myphone = SmartPhone("Pixel", "p1") 之後呼叫 myphone.ringing(),在 ringing(self) 裡的 self 是什麼?

第 1 次作答

繼承與方法覆寫

寫成 class 子類別(父類別):,子類別就繼承父類別所有的屬性與方法,只需要寫「不一樣的地方」。

  • 方法覆寫:子類別定義和父類別同名的方法,就會取代父類別的版本
  • super().__init__(...):在子類別的方法裡呼叫父類別的同名方法,常用在建構子,先讓父類別設定共同的資料
  • Python 允許一個類別同時繼承多個父類別(多重繼承),初學先掌握單一繼承即可

下面的動畫裡,introduce() 只寫在 Animal,但它呼叫的 self.speak() 會依物件實際的類別找到不同的版本:這就是多型。

繼承、覆寫與多型

Dog、Cat 繼承 Animal,各自覆寫 speak();Cat 還多了 indoor,用 super().__init__(name) 沿用父類別的建構子。迴圈對三個物件呼叫同一個 introduce(),注意每一次跳進哪一個 speak()。

想一想:繼承與 self

1.

下面的程式會印出什麼?

class A:
    def hi(self):
        return "A"
    def show(self):
        print(self.hi(), end=" ")

class B(A):
    def hi(self):
        return "B"

B().show()
A().show()
2.

下面的程式執行時會發生什麼事?

class P:
    def ring():
        print("ring")

P().ring()
第 1 次作答

實作:矩形與正方形

完成兩個 TODO:Rectangle.area() 傳回寬乘高;Square 繼承 Rectangle,建構子只收一個邊長,用 super().__init__() 把寬和高都設成邊長。完成後應該印出 矩形 12 與 正方形 25。

你的輸出
預期輸出

重點精華回顧

  • 物件=屬性(資料)+方法(函數);類別是設計圖,實例是照設計圖做出來的物件。物件導向的三個特性:封裝、繼承、多型。
  • class 類別名稱: 定義類別;類別名稱(引數) 建立實例,Python 自動呼叫 __init__() 初始化。
  • 方法的第一個參數是 self,代表物件本身;物件.方法() 呼叫時自動傳入。
  • 實例變數用 self.名稱 建立,每個實例一份;類別變數定義在類別內、方法外,所有實例共用,用 類別名稱.變數 存取。
  • 查找屬性先找實例、再找類別;對實例指派同名屬性只會新增實例變數。
  • class 子類別(父類別): 繼承;子類別定義同名方法就是覆寫;super().__init__() 呼叫父類別的建構子。
這一課完成了!
看我的學習進度
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。