不間斷 Python 挑戰 Day 19 - 物件導向程式設計:類別

閱讀時間約 10 分鐘
到目前為止,我們所學習的都是程序性的程式設計(procedural programming),也就是程式碼是透過一連串的指令組成的程序或函數,由上而下依序執行不同的程序或是呼叫函數來完成程式的功能。
Python其實是一種物件導向的程式(object oriented programming, 簡稱OOP)語言,Python的所有資料型別皆為物件,也允許開發者創造自己的物件。由於這種物件的概念易於擴充、維護與重複使用,被現代多數的程式語言所採用,也適合用來開發大型的專案。

從程序性的程式設計談起

假設我們要建立一個學生的分數登錄系統,在這個系統裡,我們需要記錄學生的姓名、各個科目的成績,也要能夠修改、查詢成績,以及增加新的科目。依照之前所學習的,可以用一個字串變數來記錄學生的姓名,用一個字典來記錄該學生每一科的分數。
student1_name = "Jack"
student1_score = {"Math": 0, "Physics": 0, "Chemistry": 0}
要修改其中一科的分數,先確認該科目是否存在於字典的鍵中,再修改對應的值。
if "Math" in student1_score:
  student1_score["Math"] = 80
同理,也可以取得其中一科的分數。
if "Math" in student1_score:
  print(student1_score["Math"])
若要新增一個新的科目,可直接增加一組鍵值對。
if "Art" not in student1_score:
  student1_score["Art"] = 0
接著我們要再登錄第二位學生的分數,以上的流程就要再重複一遍,似乎也還好,但如果有100位,甚至1000位學生的成績要登錄,這個過程就很可能變得很冗長且不易維護。
student2_name = "Rose"
student2_score = {"Math": 0, "Physics": 0, "Chemistry": 0}
...
...

物件導向程式設計-類別(Class)

就以上的觀察,我們可以這樣歸類:每位學生都是一個獨立的個體,屬於「學生」這個類別,每位學生都有不同的名字、分數,這些屬於每位學生個別的屬性(attribute),我們可以登錄或查詢每位學生各個科目的分數,或是新增新的科目,這些動作就屬於每位學生可以操作的方法(method);就如同在Python中,字典的資料型態是一個類別,我們所創造的每一個字典型態的資料都是字典這個類別的實體(instance),也稱為物件(object),而在字典一節所提過的keys()、values()、items()等就屬於字典的方法。

定義類別

類別的名稱,根據PEP 8的建議,要將所有單字合併,並且開頭的字母要大寫。定義類別的基本語法如下:
class MyClass:
  ......
以前例來說,我們可以定義一個Student類別,這裡的pass語法表示該區塊內容可以先跳過不執行。
class Student:
  pass

類別的初始化(Initialization)

類別的初始化是當一個宣告為這個類別的物件被建立時所會自動執行的方法,也稱為建構方法(constructor),它有一個固定的名稱為「__init__(self)」,其中的self是必須的,它代表了這個類別創造的物件本身,在初始化時會自動傳入。
下例中建立了一個空的建構方法,並創造一個屬於這個類別的student_1的物件。
class Student:
  # initialiation
  def __init__(self):
    pass
# create an object
student_1 = Student()
類別的建立可以沒有「__init__(self)」這個初始化函數,代表沒有參數需要被初始化,也可以傳入額外的參數,我們在後面會看到。

類別的屬性

類別的屬性區分為類別屬性(class attribute)與實體屬性(instance attribute)。類別屬性定義於建構方法之外,如下例中的classname,它不需要創造該類別的物件即可調用,一旦它被修改,所有的物件都會受到影響。
class Student:
  # class attribute
  classname = "My Class"
  # initialiation
  def __init__(self):
    pass
# access class attribute
print(Student.classname)
# create an object
student_1 = Student()
# modify class attribute
Student.classname = "Jack's Class"
print(Student.classname)
print(student_1.classname)
執行後可看到在student_1物件被創造出來前,即可透過Student.classname取得Student類別的classname屬性,並且當它被修改後,student_1物件取得的classname屬性也跟著改變。
My Class
Jack's Class
Jack's Class
實體屬性建立於建構方法內,或是在創造物件後透過「物件.屬性」生成,若建構方法內的實體屬性需要在物件建立時被初始化,可以在初始化函數__init__(self)後帶上該參數,並在函數內指派給該實體屬性。實體屬性在物件建立之後才可被調用,每個物件的實體屬性互相獨立,修改任一個物件的實體屬性不會影響到其它物件。
如以下範例,當創建Student類別的物件時傳入學生姓名到__init__(self, name)的name中,並指派給self.name,每個物件都有獨立的self.name屬性;此外,也建立了存放學生科目與成績的字典self.score。
class Student:
  # class attribute
  classname = "My Class"
  # initialiation
  def __init__(self, name):
    # instance attribute
    self.name = name
    self.score = {"Math": 0, "Physics": 0, "Chemistry": 0}
# create an object
student_1 = Student("Jack")
student_2 = Student("Rose")
print(student_1.name)
print(student_2.name)
執行結果:
Jack
Rose

類別的方法

類別方法的建立方式和前面提到的函數類似,差異在於類別方法和建構方法同樣必須傳入self參數,代表這個類別創造的物件本身,並且類別方法只有該類別所創造的物件才可調用。
以下範例中延續前面的架構,並新增了三個類別方法,分別操作登錄成績、查詢成績與新增科目。
class Student:
  # class attribute
  classname = "My Class"
  # initialization
  def __init__(self, name):
    # instance attribute
    self.name = name
    self.score = {"Math": 0, "Physics": 0, "Chemistry": 0}
  # methods
  def set_score(self, subject, score):
    if subject in self.score:
      self.score[subject] = score
  def get_score(self, subject):
    if subject in self.score:
    print(self.score[subject])
  def add_subject(self, subject):
    if subject not in self.score:
      self.score[subject] = 0
回到最一開始的例子,當我們需要完成一個學生的建檔、登錄成績、查詢成績與新增科目,只需要以下四行程式碼:
student_1 = Student("Jack")
student_1.set_score("Math", 80)
student_1.get_score("Math")
student_1.add_subject("Art")
增加新的學生時,Student類別可以重複被使用,不需再增加額外的資料結構與方法。
student_2 = Student("Rose")
student_2.set_score("Physics", 90)
student_2.get_score("Physics")
student_2.add_subject("Music")

程式範例

為什麼會看到廣告
avatar-img
47會員
36內容數
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Wei-Jie Weng的沙龍 的其他內容
Python提供集合做為其資料結構,它就如同高中數學所學集合的概念,集合的內容一般來說是具有某種特性的事物的整體,例如考試分數及格的群體、數字1到100內的所有奇數、球箱內所有球的顏色等。因此,在一個集合中,每個元素的地位都是相同且無序,並且只能出現一次,集合和集合之間,也可以進行交集、聯集、差集等
Python依據變數有效的範圍可以區分為全域變數(Global variable)或區域變數(Local variable)。在函數內宣告的變數為區域變數,有效範圍只有在函數內,函數外部無法引用這個變數;在函數以外宣告的變數為全域變數,它的有效範圍為整個檔案,並且在函數內部也可以引用這個變數。
這篇文章將利用之前所學過的一些東西,包括if敘述、串列、while迴圈、函數等等的觀念,來實作一個撲克牌的小遊戲-21點。
在前面的文章中我們學習了關於字典的基本用法,今天再討論更多關於字典的其它用法,以及它和串列、元組等的關聯。
在程式設計中,我們會使用到一些固定不會變動的資料內容,例如一年的月份、物體的邊長、過去一周的氣溫等等,使用串列的結構固然也可以用來儲存這些資料,但串列可以被新增或刪除,不能有效保護這類不可變動的資料。因此,Python也提供了另一種形式的資料結構,稱為元組,它的資料結構和串列相同,但資料的內容不可變
當我們查字典時,會先找到想查詢的單字在字典裡的位置,才能在那個位置找到單字的定義;在Python中,也有一個類似的資料結構稱作字典,字典的鍵(key)就對應到我們要查詢的單字,字典的值(value)則是該單字的定義。
Python提供集合做為其資料結構,它就如同高中數學所學集合的概念,集合的內容一般來說是具有某種特性的事物的整體,例如考試分數及格的群體、數字1到100內的所有奇數、球箱內所有球的顏色等。因此,在一個集合中,每個元素的地位都是相同且無序,並且只能出現一次,集合和集合之間,也可以進行交集、聯集、差集等
Python依據變數有效的範圍可以區分為全域變數(Global variable)或區域變數(Local variable)。在函數內宣告的變數為區域變數,有效範圍只有在函數內,函數外部無法引用這個變數;在函數以外宣告的變數為全域變數,它的有效範圍為整個檔案,並且在函數內部也可以引用這個變數。
這篇文章將利用之前所學過的一些東西,包括if敘述、串列、while迴圈、函數等等的觀念,來實作一個撲克牌的小遊戲-21點。
在前面的文章中我們學習了關於字典的基本用法,今天再討論更多關於字典的其它用法,以及它和串列、元組等的關聯。
在程式設計中,我們會使用到一些固定不會變動的資料內容,例如一年的月份、物體的邊長、過去一周的氣溫等等,使用串列的結構固然也可以用來儲存這些資料,但串列可以被新增或刪除,不能有效保護這類不可變動的資料。因此,Python也提供了另一種形式的資料結構,稱為元組,它的資料結構和串列相同,但資料的內容不可變
當我們查字典時,會先找到想查詢的單字在字典裡的位置,才能在那個位置找到單字的定義;在Python中,也有一個類似的資料結構稱作字典,字典的鍵(key)就對應到我們要查詢的單字,字典的值(value)則是該單字的定義。
你可能也想看
Google News 追蹤
Thumbnail
這篇文章介紹物件導向程式設計(OOP)的基本概念,包括類和物件的定義以及四大核心概念:封裝、繼承、多型和抽象。讀者將瞭解如何在Python中定義類和物件,並學習如何使用這些OOP特性來構建更具組織性和可維護性的程式碼。透過實例,文章探討如何將真實世界的物件模擬到程式設計中。
Thumbnail
在程式設計中,變數是儲存資料的基本單位,而型別則決定了資料的格式及使用方式。本文介紹了 Python 開發中的多種資料型別,包括整型、浮點型、字串、布林型及複數型,還提供了變數命名的規則及其使用方法。進一步探索運算子,包括比較運算子和邏輯運算子,以增強程式的邏輯判斷能力。
Thumbnail
今天要來介紹的是Python中資料型別的函數, 這幾天學習的素材是Youtube上“程式柴大大的Python 6 小時初學者課程”,一步一步帶著大家操作並解,學習中也別忘了要多多練習,練習的部分我是把我學到的東西請Chatgpt幫我出類似的題型並讓我練習。 以下我先寫出一個簡單的code,再加以
Thumbnail
本章節是Java入門的第八天,主要介紹物件導向的概念。這包括了類別、建構子、存取修飾子、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、Lambda表達式、泛型和反射等主題。每個主題都配有相關的程式碼範例,以協助讀者更好地理解這些概念。
Thumbnail
這個章節主要介紹了Swift程式語言中物件導向程式設計的基本概念,包括類別、建構子、公開、私有、受保護等等的概念。同時,也介紹了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射等進階特性。
Thumbnail
本章節是一個初級的 TypeScript 教學,主要介紹了 TypeScript 中物件導向程式設計的各種核心概念,包括類別、建構子、存取修飾子、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等。每個概念都通過詳細的解釋和實例代碼來進行深入的介紹。
Thumbnail
這一節談的是用物件導向程式設計(object-oriented programming, OOP)的方式來實作隨機漫步。
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。
Thumbnail
在使用類別創建實例時,輸入的屬性的都要定義好資料型態,例如dog_1 = Dog("Buddy", 3),有沒有輸入一段字串讓他自己判斷的方法阿? 有的就是使用classmethod: classmethod 是一種裝飾器,它用於定義類別方法。類別方法與實例方法不同,它們被綁定到類別而不是實例。
Thumbnail
本文讓我們來淺談一下類別是什麼? 若想看詳細一點的python官方教學可點此連結 Python 的類別(Class)是一種面向物件導向程式設計的概念,讓你能夠創建具有屬性和方法的物件。類別是對現實世界中事物的抽象,它包含數據和操作這些數據的方法。它非常的抽象,想像一個類別就像是一個蛋糕模具,
Thumbnail
這篇文章介紹物件導向程式設計(OOP)的基本概念,包括類和物件的定義以及四大核心概念:封裝、繼承、多型和抽象。讀者將瞭解如何在Python中定義類和物件,並學習如何使用這些OOP特性來構建更具組織性和可維護性的程式碼。透過實例,文章探討如何將真實世界的物件模擬到程式設計中。
Thumbnail
在程式設計中,變數是儲存資料的基本單位,而型別則決定了資料的格式及使用方式。本文介紹了 Python 開發中的多種資料型別,包括整型、浮點型、字串、布林型及複數型,還提供了變數命名的規則及其使用方法。進一步探索運算子,包括比較運算子和邏輯運算子,以增強程式的邏輯判斷能力。
Thumbnail
今天要來介紹的是Python中資料型別的函數, 這幾天學習的素材是Youtube上“程式柴大大的Python 6 小時初學者課程”,一步一步帶著大家操作並解,學習中也別忘了要多多練習,練習的部分我是把我學到的東西請Chatgpt幫我出類似的題型並讓我練習。 以下我先寫出一個簡單的code,再加以
Thumbnail
本章節是Java入門的第八天,主要介紹物件導向的概念。這包括了類別、建構子、存取修飾子、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、Lambda表達式、泛型和反射等主題。每個主題都配有相關的程式碼範例,以協助讀者更好地理解這些概念。
Thumbnail
這個章節主要介紹了Swift程式語言中物件導向程式設計的基本概念,包括類別、建構子、公開、私有、受保護等等的概念。同時,也介紹了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射等進階特性。
Thumbnail
本章節是一個初級的 TypeScript 教學,主要介紹了 TypeScript 中物件導向程式設計的各種核心概念,包括類別、建構子、存取修飾子、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等。每個概念都通過詳細的解釋和實例代碼來進行深入的介紹。
Thumbnail
這一節談的是用物件導向程式設計(object-oriented programming, OOP)的方式來實作隨機漫步。
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。
Thumbnail
在使用類別創建實例時,輸入的屬性的都要定義好資料型態,例如dog_1 = Dog("Buddy", 3),有沒有輸入一段字串讓他自己判斷的方法阿? 有的就是使用classmethod: classmethod 是一種裝飾器,它用於定義類別方法。類別方法與實例方法不同,它們被綁定到類別而不是實例。
Thumbnail
本文讓我們來淺談一下類別是什麼? 若想看詳細一點的python官方教學可點此連結 Python 的類別(Class)是一種面向物件導向程式設計的概念,讓你能夠創建具有屬性和方法的物件。類別是對現實世界中事物的抽象,它包含數據和操作這些數據的方法。它非常的抽象,想像一個類別就像是一個蛋糕模具,