A language feature would not be worthy of the name “class” without supporting inheritance.
如果沒有支援繼承,「class」這個語言特色就不值得被稱為 class。
–Python 官方說明書
class Car:
def __init__(self, engine, price, speed):
self.engine = engine
self.price = price
self.speed = speed
def drive(self):
print('GoGO')
def accelerate(self):
print('go ahead')
class AirPlane:
def __init__(self, engine, price, height):
self.engine = engine
self.price = price
self.height = height
def drive(self):
print('GoGO')
def fly(self):
print('up')
class Motorcycle:
def __init__(self, engine, price):
self.engine = engine
self.price = price
def drive(self):
print('GoGO')
def easter_egg(self):
print('Never gonna give you up')
以上三個 Class 有大量重複的屬性跟方法,當程式碼達上百行或更多這樣的行為可能更多,違反物件導向程式設計中的 一次且僅一次
Once and only once, OAOO
又稱為 Don't repeat yourself, DRY
或 One rule, one place
但有時,為了可讀性,或避免耦合,或過早重構,應放棄DRY原則
class Transportation:
def __init__(self, engine, price):
self.engine = engine
self.price = price
def drive(self):
print('GoGO')
class Car(Transportation):
def __init__(self, engine, price, speed):
super().__init__(engine, price)
self.speed = speed
def accelerate(self):
print('go ahead')
class AirPlane(Transportation):
def __init__(self, engine, price, height):
super().__init__(engine, price)
self.height = height
def fly(self):
print('up')
class Motorcycle(Transportation):
def __init__(self, engine, price):
super().__init__(engine, price)
def easter_egg(self):
print('Never gonna give you up')
這裡的 Transportation
稱為 Base Class (父類別)
而 Car
, Airplane
, Motorcycle
則是 Transportation
的 Sub Class (子類別)
Python3 可以直接用 super() 來呼叫父類別
Python2 則必須用 super(Class, self)
如範例程式就要改成super(Transportation, self).__init__
Python 提供 isinstance(object_name, class_name)
來檢查一個物件與一個類別的關係
class Student:
pass
class Teacher:
pass
sun = Teacher()
print(isinstance(sun, Student)) # False
print(isinstance(sun, Teacher)) # True
isinstance
也能檢查到父類別
還有 issubclass(object_name, object_name)
提供了檢查類別間關係的方式
class Student:
pass
class Teacher(Student):
pass
sun = Teacher()
print(isinstance(sun, Student)) # True
print(isinstance(sun, Teacher)) # True
print(issubclass(Student, Teacher)) # False
print(issubclass(Teacher, Student)) # True
print(issubclass(Student, object)) # True 所有 class 都間接或直接繼承了 object
print(issubclass(Teacher, object)) # True
class Computer:
def hi(self):
print("I'm computer.")
class AMD(Computer):
def hi(self):
print("I'm AMD.")
A = AMD()
A.hi() # output: I'm AMD.
如果子類別有與父類別同名的方法,則子類別會覆寫該方法,稱為 Method Overriding
需要使用同名方法的話可以在子類別中以 super
呼叫
class AMD(Computer):
def hi(self):
super().hi()
print("I'm AMD.")
A = AMD()
A.hi()
# output:
# I'm computer.
# I'm AMD.
class Animal:
def __init__(self, height, weight):
self.height = height
self.weight = weight
def hello(self):
print(f"I'm {self.height} cm tall and weight {self.weight} kg.")
def fly(self):
pass
class Human(Animal):
def __init__(self, height, weight, age):
super().__init__(height, weight)
self.age = age
def hello(self):
super().hello()
print(f"I'm {self.age} years old.")
class Taiwanese(Human):
def __init__(self, height, weight, age):
super().__init__(height, weight, age)
class Student(Taiwanese):
def __init__(self, height, weight, age, school):
super().__init__(height, weight, age)
self.school = school
def hello(self):
super().hello()
print(f"I study at {self.school}.")
magical = Student(165, 50, 19, 'NTNU')
magical.hello()
# output:
# I'm 165 cm tall and weight 50 kg.
# I'm 19 years old.
# I study at NTNU.
多層繼承通常不建議超過兩層,否則程式碼較多時不易維護,且因較為複雜有時會繼承到不該繼承的東西(像是 class Human
繼承 class Animal
就莫名其妙會飛了)
class Phone:
def __init__(self, cpu, size):
self.cpu = cpu
self.size = size
def hi(self):
print("I'm Phone.")
class Apple:
def __init__(self, model):
self.model = model
def hi(self):
print("I'm Apple.")
class iPhone(Phone, Apple):
def __init__(self, model, cpu, size, gen):
Phone.__init__(self, cpu, size)
Apple.__init__(self, model)
self.gen = gen
def hello(self):
print(f"I'm gen {self.gen} {self.model}." )
myphone = iPhone('iPhone mini', 'A15', 5.4, 13)
myphone.hi()
myphone.hello()
# output:
# I'm Phone.
# I'm gen 13 iPhone mini.
多重繼承是一種類別同時有兩個或以上父類別
要特別注意內部如果有同名屬性或方法會依繼承順序以遞迴方式繼承
(範例中是先 Phone
再 Apple
,因此調用 hi()
時的輸出為 Phone
的 I'm Phone
)
包含魔術方法也是,因此使用多重繼承時的初始化方式也不一樣
除了魔術方法在命名上必須按照標準,在使用多重繼承時應盡可能避免同名方法,免得換別人維護那份程式碼的時候因為交換繼承的順序而產生不如預期的結果
在某些情形下依然能使用 super()
來調用多個父類別的方法,有空的可以試試看
Just trial and error.
是非題 數位製造不僅是3D列印、更是製造方式的數位化,不是只有將設計方式數位化、還包含了材料和過程。創客風潮是一種懷舊的叛逆次文化,以創意為口號舉辦Maker Faire及一些藝文活動。 [ ] T F IoT物聯網是網際網路、傳統電信網等資訊承載體,讓所有能行使獨立功能的普通物體實作互聯互通的網路。 [x] T
Oct 26, 2022File I/O I/O = Input/Output 名詞介紹 Directory 目錄 其實就是資料夾,不過稍微廣義一點,像是我們很少把根目錄叫做資料夾 Flie 檔案 檔案大致上可以分兩種,文字檔 (text file) 跟二進位檔 (binary file)
Apr 16, 2022Python :::success 有6題(0-5)小練習題,會用綠框框包起來,做做看拜託,神奇想題目想很久 ::: I/O 輸入與輸出 print() 預設 sep=' ' (以空格分隔)
Feb 27, 2022專案連結 遊戲規則 選角 控制WASD 打小怪提升角色數值 攻速、跑速、最大護盾、最大血量 三關 打掉BOSS可以進下一關 三關打完挑戰成功 受傷先扣護盾 護盾脫戰隨時間(5s)恢復 護盾用完受傷扣血量 血量歸零遊戲結束
Jan 5, 2022or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up