Python 的物件導向程式設計提供繼承機制,允許建立新類別並繼承既有類別的屬性與方法,減少程式碼重複並建立類別間的層次結構。同時,運算元多載讓開發者能重新定義運算元行為,使其適用於自定義類別,提升程式碼的彈性與可讀性。理解繼承與多載,能有效運用 Python 物件導向的特性,建構更具彈性與可維護性的程式碼。
物件導向程式設計:類別、物件與繼承
在物件導向程式設計中,運算元多載(Operator Overloading)是一種重要的特性,它允許開發者重新定義運算元的行為,使其適用於自定義的類別。
運算元多載的實作
Python 中的運算元多載是透過特殊方法(Special Methods)來實作的。例如,當我們使用 + 運算元對兩個物件進行加法運算時,Python 會自動呼叫 __add__ 方法。
程式範例:運算元多載
class AddDemo:
def __init__(self, value):
self.value = value
def __add__(self, other):
print('物件1的值 =', self.value)
print('物件2的值 =', other.value)
print('兩個物件相加的結果是:', end='')
return self.value + other.value
Ob1 = AddDemo(20)
Ob2 = AddDemo(30)
Ob3 = Ob1 + Ob2
print(Ob3)
內容解密:
- 在這個範例中,我們定義了一個名為
AddDemo的類別,並實作了__add__方法。 - 當我們使用
+運算元對Ob1和Ob2進行加法運算時,Python 會自動呼叫__add__方法。 - 在
__add__方法中,我們列印了兩個物件的值,並傳回了它們的和。
比較運算元的多載
除了算術運算元之外,我們還可以多載比較運算元,例如 <、> 和 <=。這些運算元分別對應於 __lt__、__gt__ 和 __le__ 方法。
程式範例:比較運算元的多載
class CmpOprDemo:
def __init__(self, X):
self.X = X
def __lt__(self, other):
print('物件1的值 =', self.X)
print('物件2的值 =', other.X)
print('物件1 < 物件2 :', end='')
return self.X < other.X
def __gt__(self, other):
print('物件1 > 物件2 :', end='')
return self.X > other.X
def __le__(self, other):
print('物件1 <= 物件2 :', end='')
return self.X <= other.X
Ob1 = CmpOprDemo(20)
Ob2 = CmpOprDemo(30)
print(Ob1 < Ob2)
print(Ob1 > Ob2)
print(Ob1 <= Ob2)
內容解密:
- 在這個範例中,我們定義了一個名為
CmpOprDemo的類別,並實作了__lt__、__gt__和__le__方法。 - 當我們使用
<、>和<=運算元對Ob1和Ob2進行比較時,Python 會自動呼叫相應的方法。 - 在這些方法中,我們列印了比較的結果,並傳回了比較的值。
參考相等性與物件相等性
在 Python 中,有兩種方式可以檢查物件的相等性:參考相等性和物件相等性。
- 參考相等性是指兩個變數是否指向同一個物件,可以使用
is運算元來檢查。 - 物件相等性是指兩個物件的值是否相等,可以使用
==運算元來檢查。
內建函式的多載
除了運算元之外,我們還可以多載內建函式,例如 abs()、float() 和 str()。這些函式分別對應於 __abs__、__float__ 和 __str__ 方法。
繼承
繼承是物件導向程式設計中的一個重要特性,它允許我們建立新的類別,並繼承現有類別的屬性和方法。被繼承的類別稱為基底類別或超類別,而新的類別稱為衍生類別或子類別。
繼承的優點
- 程式碼重用:繼承允許我們重用現有類別的程式碼,避免了重複編寫相同的程式碼。
- 層次結構:繼承可以建立類別之間的層次結構,使得程式碼更加有組織和易於維護。
繼承的實作
在 Python 中,我們可以使用 class 關鍵字來定義一個新的類別,並使用 (基底類別名稱) 語法來指定基底類別。
class 基底類別:
def __init__(self):
pass
class 衍生類別(基底類別):
def __init__(self):
super().__init__()
內容解密:
- 在這個範例中,我們定義了一個名為
基底類別的基底類別和一個名為衍生類別的衍生類別。 - 衍生類別繼承了基底類別的屬性和方法,並可以使用
super()函式來呼叫基底類別的方法。
物件導向程式設計:類別、物件與繼承
繼承是物件導向程式設計中的一個強大功能,它允許開發者從現有的類別中建立新的類別。繼承的過程可以根據基底類別的數量和巢狀衍生的程度進行簡單或複雜的分類別。
繼承的型別
繼承可以分為以下幾種型別:
單一繼承:一個新的類別從單一的基底類別衍生而來。
- 例如,類別
Q從類別P衍生而來。 - 圖示:
P | Q
- 例如,類別
多層繼承:一個類別從另一個衍生類別中衍生而來,形成多層次的繼承關係。
- 例如,類別
Z從類別Y衍生而來,而類別Y又從類別X衍生而來。 - 圖示:
X | Y | Z
- 例如,類別
多重繼承:一個新的類別可以從多個基底類別中衍生而來。
- 例如,類別
Z從類別X和類別Y衍生而來。 - 圖示:
X Y \ / Z
- 例如,類別
物件類別
在 Python 中,每個類別都預設繼承自 object 類別。object 類別是 Python 函式庫中定義的基本類別。
繼承的詳細說明
繼承允許開發者建立新的類別,並繼承現有類別的屬性和方法。在 Python 中,定義繼承的語法如下:
class 衍生類別名稱(基底類別名稱):
衍生類別的主體
若要繼承多個基底類別,可以使用逗號分隔的基底類別名稱列表:
class 衍生類別名稱(基底類別1, 基底類別2, ...):
衍生類別的主體
程式範例 1:單一繼承
class A:
def __init__(self):
print('Hello, 我在基底類別')
class B(A):
def __init__(self):
super().__init__()
print('Wow!! 很棒!我在衍生類別')
ob2 = B()
輸出結果:
Hello, 我在基底類別
Wow!! 很棒!我在衍生類別
程式範例 2:屬性繼承
class Point:
def set_coordinates(self, x, y):
self.x = x
self.y = y
class NewPoint(Point):
def draw(self):
print(f'在 X 軸上定位點 X = {self.x}')
print(f'在 Y 軸上定位點 Y = {self.y}')
p = NewPoint()
p.set_coordinates(10, 20)
p.draw()
輸出結果:
在 X 軸上定位點 X = 10
在 Y 軸上定位點 Y = 20
程式範例 3:多層繼承
class A:
name = ''
age = 0
class B(A):
height = ''
class C(B):
weight = ''
def read(self):
self.name = input('請輸入姓名:')
self.age = int(input('請輸入年齡:'))
self.height = input('請輸入身高:')
self.weight = int(input('請輸入體重:'))
def display(self):
print(f'姓名:{self.name}')
print(f'年齡:{self.age}')
print(f'身高:{self.height}')
print(f'體重:{self.weight}')
c = C()
c.read()
c.display()
輸出結果取決於使用者的輸入。
#### 內容解密:
上述範例展示了 Python 中物件導向程式設計的基本概念,包括單一繼承、多層繼承和屬性繼承。透過這些範例,我們可以看到如何定義基底類別和衍生類別,以及如何使用繼承來擴充套件現有類別的功能。
繼承的作用與邏輯:
- 繼承允許程式碼重用,減少重複程式碼。
- 透過繼承,可以建立具有層次結構的類別體系。
- 子類別可以存取父類別的屬性和方法,也可以新增自己的屬性和方法,或是覆寫父類別的方法。
程式碼分析:
- 在單一繼承的範例中,
B繼承了A的屬性和方法,並在其基礎上新增了自己的初始化方法。 - 在屬性繼承的範例中,
NewPoint繼承了Point的set_coordinates方法,並新增了draw方法來輸出座標。 - 在多層繼承的範例中,
C繼承了B的屬性和方法,而B又繼承了A的屬性和方法,形成了一個多層次的繼承結構。
這些範例共同展示了 Python 中物件導向程式設計的靈活性和強大功能。
多重繼承與super()的使用
在物件導向程式設計中,繼承是一種重要的概念。Python 支援單一繼承和多重繼承。多重繼承允許一個子類別繼承多個父類別的屬性和方法。本文將探討多重繼承的概念,並介紹如何使用 super() 函式來呼叫父類別的建構子和屬性。
多重繼承
多重繼承是指一個子類別可以繼承多個父類別的屬性和方法。這種機制使得子類別可以獲得多個父類別的特性,從而實作更複雜的功能。
多重繼承範例
class A:
a = 0
class B:
b = 0
class C(A, B):
c = 0
def read(self):
self.a = int(input('Enter the Value of a: '))
self.b = int(input('Enter the value of b: '))
self.c = int(input('Enter the value of c: '))
def display(self):
print('a = ', self.a)
print('b = ', self.b)
print('c = ', self.c)
Ob1 = C()
Ob1.read()
Ob1.display()
程式碼解析:
- 類別定義:定義了三個類別
A、B和C,其中C繼承了A和B。 read方法:用於讀取使用者輸入的值並賦給a、b和c屬性。display方法:用於顯示a、b和c的值。- 例項化與方法呼叫:建立了
C的例項Ob1,並呼叫了read和display方法。
使用super()呼叫父類別建構子
在子類別中,如果需要呼叫父類別的建構子或屬性,可以使用 super() 函式。super() 允許子類別存取父類別的屬性和方法,避免了程式碼的重複。
使用super()的範例
class Demo:
def __init__(self, A, B, C):
self.a = A
self.b = B
self.c = C
def display(self):
print(self.a, self.b, self.c)
class NewDemo(Demo):
def __init__(self, A, B, C, D):
super().__init__(A, B, C) # 呼叫父類別的建構子
self.d = D
def display(self):
super().display() # 呼叫父類別的display方法
print(self.d)
D1 = NewDemo(10, 20, 30, 40)
D1.display()
程式碼解析:
- 類別定義:定義了兩個類別
Demo和NewDemo,其中NewDemo繼承了Demo。 super().__init__(A, B, C):在NewDemo的建構子中使用super()呼叫了Demo的建構子,初始化了a、b和c屬性。super().display():在NewDemo的display方法中使用super()呼叫了Demo的display方法,顯示了a、b和c的值。- 例項化與方法呼叫:建立了
NewDemo的例項D1,並呼叫了display方法。