在下一篇文章會學習 Object Orientation Program (OOP) ,它是其中一種程式設計方法,是以物件 (Object) 作為基本單位。這個概念相對抽象,需要多點時間消化。而在這一篇文章先來介紹什麼是 Class 和 Object,之後對 OOP 的概念才有更好的理解。
Class (類別) 就像是設計藍圖,而 Object (物件) 則是透過設計藍圖 Class 來生成的實體。
概念就像房子的設計藍圖,可以建起很多的房子。
定義 Class 主要會分 2 個部分:
Attribute (屬性)
用來定義 Object 的屬性資料,可以理解成屬於 Object 的變數。
Attribute 分為 2 種:
Class Attribute (類別屬性)
# 建立 class 命為 Person
class Person:
# 建立 class attribute
name = "Anonymous"
### 主程式
# 生成 object
person_1 = Person()
person_2 = Person()
# person_1.name 取得 "person_1" object 的 "name" attribute
print(f"Person 1: {person_1.name}")
print(f"Person 2: {person_2.name}")
# 只修改當前 object,不影響其他 object
person_1.name = "Mary"
print(f"Person 1: {person_1.name}")
print(f"Person 2: {person_2.name}")
# 原來的 class 不受影響,生成的 object attribute 資料依舊
person_3 = Person()
print(f"Person 3: {person_3.name}")
Output:
Person 1: Anonymous
Person 2: Anonymous
Person 1: Mary
Person 2: Anonymous
Person 3: Anonymous
Instance Attribute (實例屬性)
屬於 Object 的屬性
可以是在生成 Object 時透過 建構子 (Constructor) 帶入參數建立 Instance attribute。
建構子會用 def __init__(self)
來定義,是 object 初始化的意思,定義 object 生成時會有什麼 attribute。
class Person:
# 建構子 Constructor
# 必定帶有參數 self,代表當前 object 的自身,可被引用來取得並資料
def __init__(self, name):
# 應用參數建立 Instance attribute
# self.name 為當前 object 的 name attribute 指派為參數的值
self.name = name
# 建 Object 時帶入參數
person_1 = Person("Mary")
person_2 = Person("John")
print(f"Person 1: {person_1.name}")
print(f"Person 2: {person_2.name}")
Output:
Mary
John
或是生成 Object 以後增加 instance attribute
class Person:
def __init__(self, name):
self.name = name
person_1 = Person("Mary")
# 在 object 新增 instance attribute
person_1.age = 18
person_2 = Person("John")
person_2.sex = "M"
print(person_1.name)
print(person_1.age)
print(person_2.name)
print(person_2.sex)
# 應用 object 沒有的 instance attribute 會噴錯
print(person_2.age)
Output:
Mary
18
John
M
...
...
AttributeError: 'Person' object has no attribute 'age'
Methods (方法):
寫在 class 內的 function
被稱為 method
,用來定義 Object 可用的操作。分為以下 3 種:
Instance Method
self
的參數,代表 object 自身,可應用 self 來取得 instance attribute 或 instance method。class Person:
def __init__(self, name):
self.name = name
# 建立 instance method
def say_hi(self):
# 透過 self 可應用 instance attribute
print(f"Hi, I am {self.name}")
person = Person("John")
# 應用時,不需要傳值到 self
person.say_hi()
Class Methods
@classmethod
作標記cls
參數,代表 class 自身,可應用來取得 class attribute 或其他 class method。class Toy:
price = 100
def get_current_price(self):
print(f"Current Price: {self.price}")
# 建立 class method
@classmethod
def get_original_price(cls):
# 透過 cls 可應用 class attribute
print(f"Original Price: {cls.price}")
car = Toy()
# 修改 instance attribute (price)
car.price = 80
car.get_original_price() # 將會取得 instance attribute (price)
car.get_current_price() # 將會取得 class attribute (price)
# 不用生成 object,可直接使用
Toy.get_original_price() # 同樣可取得 class attribute (price)
Toy.get_current_price() # 會噴錯,因為不是 instance object
Output:
Original Price: 100
Current Price: 80
Original Price: 100
...
...
TypeError: get_current_price() missing 1 required positional argument: 'self'
Static Method
@staticmethod
作標記self
或 cls
參數,這種 Method 都不需要用到 attribute。class Person:
# 建立 static method
@staticmethod
def say_hello():
print("Hello World!")
# Class 可直接使用
Person.say_hello()
# Object 也可使用
john = Person()
john.say_hello()
Output:
Hello World!
Hello World!
利用 Class 可以去定義物件的 Attribute (屬性) 和 Method (方法),可衍生多個帶有這些屬性和功能的 Object。讓 Object 都成為獨立的個體,應用自己擁有的屬性,去作不同的運算。
補充:上一篇有提到在 Python 所有資料都是 Object,其實所有型別如 str, int, float 都是由 class 定義,每個資料都是實體 Object,可以應用 class 對各種型別定義的方法。
像是 str 的 object,有非常多內建的 Method 可以使用,需要可參看官方文件
以下是一些簡單的例子,可見 str 為 object,因此會有內建的 method 可應用。temp = "abc" # 把字串都轉為大寫 print(temp.upper()) # 把字串都轉為小寫 print(temp.lower()) # 把字串中 a 取代為 - print(temp.replace('a', '-'))
Output:
ABC abc -bc