Python 101 基礎教學 (10) - 物件導向 Object-Oriented Programming

物件導向 Object-Oriented Programming(OOP) 是以物件的形式去描述你資料應有的行為。就像我們在現實世界中定義貓、狗、人、車等等一樣,都有自己的運作方式。程式語言中我們也可以把資料想成物件,用物件導向去定義你的每個物件該如何運作。

使用物件導向的好處,個人人為因為更貼近人平常看待事物的方式,所以一但把包裝成物件的方式也會更容易組織以及理解。

類別(Class)與物件/實體(Instance)

# 物件導向的最基礎,我們定義class,然後用它宣告我們的物件/實體(instance)
# class 可以定義attribute(成員)、method(方法),還有一些既定方法像是初始化__init__
# class裡的method,跟function基本上是一樣的,但第一個參數是self,會指向此實體本身

# 定義一個class叫做Person
# 我們習慣把class的名稱定義成UpperCaseCamelCase,字的開頭大寫
# 如果有多個字組成則在每個字的開頭大寫連起來
class Person:
  
  # 定義class attribute,所有實體會共用它
  kind = 'Person'
  
  # 初始化,當宣告實體的時候這個方法會被呼叫
  # 用self.xxx來定義實體的 attribute,每個被宣告的實體會有自己的attribute 
  def __init__(self, name, age):
    self.name = name; 
    self.age = age;
  
  # 定義實體的方法
  def say_hi(self):
    print(
      f'Hi, my name is {self.name}, I am {self.age} years old'
    )
  
# 使用定義好的Class宣導實體(instance)
mike = Person('Mike', 5) # 帶進去的參數Mike與5分辨對應__init__裡的name與age
john = Person('John', 10)

# 呼叫實體的方法
mike.say_hi() # output: Hi, my name is Mike, I am 5 years old
john.say_hi() # output: Hi, my name is John, I am 10 years old

# 印出實體attribute
print(mike.name) # output: Mike
print(john.name) # output: John

# class attribute是共用的,不管是class本身或是instance都能使用
print(mike.kind) # Person
print(Person.kind) # Person

有了 class 以後,我們就可以更有效的包裝各式各樣的資料。其實前幾篇文章介紹的一些基本資料類型也是物件的一種,所以它們才會有自己的一些方法,當然這些是Python 內建好的,直接使用就可以了。

a = [2, 3, 4] # a是一個list,但他也是一個物件
a.append(1) # list提供append這個方法給我們使用

s = {1, 2} # s是一個set,也是一個物件
s.add(3) # add是set的一個方法

繼承(Inheritance)

物件導向有四個基礎觀念,分別是繼承、抽象、封裝以及多型。由於 Python 的彈性以及 duck typing 的特性,比較難完美詮釋這些物件導向的基本觀念,這邊就不深入多談,詳情可以查看wiki

# 宣告新的class叫Student,繼承Person
class Student(Person):

  # 如果需要的話可以定義新的初始化函數,它會覆蓋掉原本Person定義好的
  def __init__(self, name, age, degree):
    
    # 使用super去呼叫parent的初始化函數,Student的parent是Person
    super().__init__(name, age)
    
    # 新的class多一個degree這個attribute
    self.degree = degree
  
  # 定義新的方法
  def tell_my_degree(self):
    print(f'I earned my {self.degree} degree')

# 宣告實體
susan = Student('Susan', 22, 'master')


# 繼承的class所宣告出的實體可以呼叫parent class定義的方法
susan.say_hi() # ouptut: Hi, my name is Susan, I am 22 years old
susan.tell_my_degree() # output: I earned my master degree

print(susan.name) # output: Susan
print(susan.degree) # output: master

物件導向只是一種設計模式,你甚至都不需要使用它也能完成各種任務,但學習物件導向能讓你對寫程式有更深層的認識,也讓你寫出來的程式更有組織性。使用一些開源框架像是 Django 等,你也需要了解如何使用 class。