Python3 教學 #05 (Ch9: Class: 繼承、建構子、多型、封裝、覆載)
本文會介紹Python的Class類別相關語法:
Python Class繼承、多型、封裝、建構子、變數、父類別的屬性/方法如何使用、覆載的語法Python也是物件導向程式語言,在學習這個部分時,可以帶入Java的觀念來記憶會更深刻喔!
(以下語法皆以Python3.6撰寫。)
Class
語法
語法很簡單就是直接使用class關鍵字來完成類別的結構!
定義類別的語法『 class 類別名稱: 』
宣告物件的方法『 物件名稱 = 類別建構子名稱(參數) 』
1 2 3 4 5 6 7 8 9 10 |
class FirstClass: """My first class in python.""" str = "Apple" def fun(self): # 在類別內的函數都至少要傳入參數self return "Hello world." my_obj = FirstClass() # 宣告一個類別為FirstClass的物件 print(my_obj.str) # 使用物件的公開變數 print(my_obj.fun()) # 使用物件的公開函數 |
建構子
建構子語法如下:
def __init__(self, 其他參數):
就算是在建構子裡面self也是必須傳入的參數喔!
值得一提的是Python不支援多建構子(multi constructor),但是可以透過預設值的方式來達成!
def __init__(self, para1=”para1預設值”, para2=”para2預設值2″):
如此一來,就可以有3種宣告方式!
使用類別自己的變數、函數都須要加上『 self.變數名稱 』才能使用!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class FirstClass: """My first class in python.""" str1 = "Apple" str2 = "IBM" def __init__(self, str1="參數1", str2="參數2"): self.str1 = str1 self.str2 = str2 def fun(self): return "Hello world." my_obj = FirstClass() print(my_obj.str1) print(my_obj.str2) print("===分隔線===") my_obj2 = FirstClass("我是參數1") print(my_obj2.str1) print(my_obj2.str2) print("===分隔線===") my_obj3 = FirstClass("我是參數1", "我是參數2") print(my_obj3.str1) print(my_obj3.str2) |
執行輸出結果如下:
1 2 3 4 5 6 7 8 |
參數1 參數2 ===分隔線=== 我是參數1 參數2 ===分隔線=== 我是參數1 我是參數2 |
Class繼承
Python Class的繼承也很簡單!語法如下:
class 類別名稱(父類別):
繼承父類別要記得實作父類別的建構子,像是下列第16行那樣!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
class Car: wheels_number = 4 # 輪胎數量 car_doors = 4 # 車門數量 passengers = 4 # 乘客數量 def __init__(self, wheels_number=4, car_doors=4, passengers=4): self.wheels_number = wheels_number self.car_doors = car_doors self.passengers = passengers # SUV也是一種車子,所以繼承Car class SUV(Car): brand_name = "" # 品牌名稱 air_bag = 2 # 安全氣囊數 sunroof = True # 是否擁有天窗 def __init__(self, wheels_number, car_doors, passengers, brand_name="", air_bag=2, sunroof=False): super().__init__(wheels_number, car_doors, passengers) self.brand_name = brand_name self.air_bag = air_bag self.sunroof = sunroof def getDetails(self): print("==== Details ====") print("Brand:", self.brand_name) print("Wheels number:", self.wheels_number) # 可直接呼叫父類別的變數(屬性) print("Doors number:", self.car_doors) # 可直接呼叫父類別的變數(屬性) print("Air-bags number:", self.air_bag) print("Sunroof:", self.sunroof) print("=================") # 宣告一台Toyota RAV的休旅車(SUV) toyota_rav = SUV(4, 5, 5, "Toyota RAV", 4, True) toyota_rav.getDetails() # 宣告一台BMW X5的休旅車 bmw_x5 = SUV(4, 5, 5, "BMW X5", 6, True) bmw_x5.getDetails() |
多型
定義兩種繼承Car的類別(SUV, Bus),同時也直接覆載(overwrite)父類別已經定義的方法!
撰寫方法如下,直接在子類別中覆載覆類別的方法即可!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
class Car: # wheels_number:輪胎數量, car_doors:車門數量, passengers:乘客數量 def __init__(self, wheels_number=4, car_doors=4, passengers=4): self.wheels_number = wheels_number self.car_doors = car_doors self.passengers = passengers def drive(self): print("Drive a car.") # SUV也是一種車子,所以繼承Car class SUV(Car): # brand_name:品牌名稱, air_bag:安全氣囊數, sunroof:是否擁有天窗 def __init__(self, wheels_number, car_doors, passengers, brand_name="", air_bag=2, sunroof=False): super().__init__(wheels_number, car_doors, passengers) self.brand_name = brand_name self.air_bag = air_bag self.sunroof = sunroof # 覆寫父類別的drive def drive(self): print("Drive this {0} to my vacation.".format(self.brand_name)) def getDetails(self): print("==== Details ====") print("Brand:", self.brand_name) print("Wheels number:", self.wheels_number) # 可直接呼叫父類別的變數(屬性) print("Doors number:", self.car_doors) # 可直接呼叫父類別的變數(屬性) print("Air-bags number:", self.air_bag) print("Sunroof:", self.sunroof) print("=================") # Bus也是一種車子,所以繼承Car class Bus(Car): # brand_name:品牌名稱, air_bag:安全氣囊數, sunroof:是否擁有天窗 def __init__(self, wheels_number, car_doors, passengers, brand_name="", air_bag=0): super().__init__(wheels_number, car_doors, passengers) self.brand_name = brand_name self.air_bag = air_bag # 覆寫父類別的drive def drive(self): print("Take this {0} to my vacation.".format(self.brand_name)) def getDetails(self): print("==== Details ====") print("Brand:", self.brand_name) print("Wheels number:", self.wheels_number) # 可直接呼叫父類別的變數(屬性) print("Doors number:", self.car_doors) # 可直接呼叫父類別的變數(屬性) print("Air-bags number:", self.air_bag) print("=================") # 宣告一台Toyota RAV的休旅車(SUV) toyota_rav = SUV(4, 5, 5, "Toyota RAV", 4, True) # 宣告一台BMW X5的休旅車 bmw_x5 = SUV(4, 5, 5, "BMW X5", 6, True) # 宣告一台Volvo Bus的巴士 volvo_bus = Bus(4, 3, 50, "Volvo Bus", 0) # 分別呼叫各種車輛的drive()方法 def letsDrive(cars): for car in cars: car.drive() letsDrive([toyota_rav, bmw_x5, volvo_bus]) |
執行結果如下:
1 2 3 |
Drive this Toyota RAV to my vacation. Drive this BMW X5 to my vacation. Take this Volvo Bus to my vacation. |
特殊用法
物件與物件之間的互動可以透過覆載下列特殊方法來個別定義!
特殊方法,例如:物件1 > 物件2
def __gt__(self, other):
以這種來實作比較self/other的屬性或方法等等的功能!
方法名稱 | 用途 |
__lt__ | 小於(<) |
__le__ | 小於等於(<=) |
__eq__ | 等於(==) |
__ne__ | 不等於(!=) |
__gt__ | 大於(>) |
__ge__ | 大於等於(>=) |
__add__ | + |
__iadd__ | += |
__sub__ | – |
__isub__ | -= |
__mul__ | * |
__imul__ | *= |
__truediv__ | / |
__itruediv__ | /= |
__floordiv__ | // |
__ifloordiv__ | //= |
__mod__ | % |
__imod__ | %= |
__pow__ | ** |
__ipow__ | **= |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
class Car: # wheels_number:輪胎數量, car_doors:車門數量, passengers:乘客數量 def __init__(self, wheels_number=4, car_doors=4, passengers=4): self.wheels_number = wheels_number self.car_doors = car_doors self.passengers = passengers def drive(self): print("Drive a car.") # SUV也是一種車子,所以繼承Car class SUV(Car): # brand_name:品牌名稱, air_bag:安全氣囊數, sunroof:是否擁有天窗 def __init__(self, wheels_number, car_doors, passengers, brand_name="", air_bag=2, sunroof=False): super().__init__(wheels_number, car_doors, passengers) self.brand_name = brand_name self.air_bag = air_bag self.sunroof = sunroof # 回傳自己的安全氣囊數是否大於其他人的安全氣囊數的真假值 def __gt__(self, other): return self.air_bag > other.air_bag # 覆寫父類別的drive def drive(self): print("Drive this {0} to my vacation.".format(self.brand_name)) def getDetails(self): print("==== Details ====") print("Brand:", self.brand_name) print("Wheels number:", self.wheels_number) # 可直接呼叫父類別的變數(屬性) print("Doors number:", self.car_doors) # 可直接呼叫父類別的變數(屬性) print("Air-bags number:", self.air_bag) print("Sunroof:", self.sunroof) print("=================") # 宣告一台Toyota RAV的休旅車(SUV) toyota_rav = SUV(4, 5, 5, "Toyota RAV", 4, True) # 宣告一台BMW X5的休旅車 bmw_x5 = SUV(4, 5, 5, "BMW X5", 6, True) # 來判斷bmw_x5的安全氣囊數是否大於toyota_rav print(bmw_x5 > toyota_rav) |