(D19)Python-封裝、多型、多繼承、重寫
阿新 • • 發佈:2018-12-08
封裝 enclosure
- 封裝是指隱藏類的實現細節,讓使用者不用關心這些細節
- 封裝的目的是讓使用者通過儘可能少的方法(或屬性)操作物件
私有屬性和方法:
- python類中以雙下劃線(’__’)開頭,不以雙下劃線結尾的識別符號為私有成員,私有成員只能用此類的方法進行訪問和修改
示例1:
# 此示例示意用私有屬性和私有方法來進行封裝 class A: def __init__(self): self.__p1 = 100 # 建立私有屬性,此屬性在類外無法訪問 def __m1(self): # 私有方法 print("__m1 私有方法被呼叫") def infos(self): print("A類的infos訪問的__p1屬性是:", self.__p1) self.__m1() # 呼叫自己的私有方法 a = A() # print(a.__p1) # 出錯 a.infos() # a.__m1() # 當前主模組不能呼叫A類的私有方法
多型 polymorphic
-
什麼是多型:
- 字面意思: 多種狀態
-
狀態:
- 靜態(編譯時狀態)
- 動態(執行時狀態)
-
多型是指在有繼承/派生關係的類中,呼叫基類物件的方法,呼叫基類物件的方法,實際能呼叫子類的覆蓋方法的現象叫多型
-
說明:
- 多型呼叫的方法與物件相關,不與型別相關
- python全部物件都只有執行時狀態(動態)
- 沒有"c++語言"裡編譯時狀態(靜態)
示例2:
# 此示例示意python的多型(動態) class Shape: '''圖形''' def draw(self): print("Shape的draw() 被呼叫") class Point(Shape): def draw(self): print("正在畫一個點") class Circle(Point): def draw(self): print("正在畫一個圓") def my_draw(s): s.draw() # s.draw呼叫誰是在執行時由s的型別動態決定 # 此處顯示出執行時狀態 shape1 = Circle() shape2 = Point() my_draw(shape1) my_draw(shape2) L = [Point(), Circle(), Point(), Point(), Circle()] for s in L:
面向物件的程式語言的特徵
封裝
繼承/派生
多型
多繼承 multiple inheritance
- 多繼承是指一個子類繼承自兩個或兩個以上的基類
語法:
- class 類名(基類名1,基類名2,…)
說明:
- 一個子類同時繼承自多個父類,父類中的方法可以同時被繼承下來
如果兩個父類中有同名的方法,則在子類中又沒有覆蓋此方法時,
呼叫結果難以確定
示例3:
# 此示例示意多繼承的語法和用法 class Car: def run(self, speed): print('車正在以', speed, '公里/小時的速度行駛') class Plane: def fly(self, height): print('飛機以海拔', height, '米的高空飛行') class PlaneCar(Plane, Car): '''PlaneCar類同時繼承是Plane和 Car類''' p1 = PlaneCar() p1.fly(10000)
多繼承的問題(缺陷)
- 識別符號(名字空間)衝突問題
- 要謹慎使用多繼承
多繼承的MRO(Method Resolution Order)等問題
- 類的__mro__屬性:
- 作用:
- 用來記錄屬性(或方法)的查詢順序
- 作用:
函式重寫 overwrite
什麼是函式重寫
- 在自定義的類內新增相應的方法,讓自定義的類生成的物件(例項)
- 像內建物件一樣進行函式操作
物件轉字串函式:
- repr(x) 返回一個能代表此物件的表示式字串,通常:
- eval(repr(obj)) = obj
- str(obj) 通過給定物件,返回一個字串(這個字串通常是給人閱讀的)
示例4:
# 此示例示意repr函式和str函式的不同
s = "I'm Teacher"
print(str(s))
print(repr(s))
class MyNumber:
def __init__(self,value):
self.data = value
def __str__(self):
print("正在呼叫__str__方法,轉換為普通字串")
s = "自定義資料%d" % self.data
return s
def __repr__(self):
return 'MyNumber(%d)' % self.data
n1 = MyNumber(100)
print(str(n1))
print(repr(n1))
# 此示例示意自定義的物件轉為python內鍵的數字型別
class MyNumber:
def __init__(self, v):
self.data = v
def __repr__(self):
return "MyNumber(%d)" % self.data
def __int__(self):
return int(self.data)
n1 = MyNumber(100.5)
n = int(n1) # 自定義型別轉為整數, 出錯!!!
print(n)
str(obj) 函式呼叫方法說明:
1. str(obj) 函式先查詢obj.__str__()方法,呼叫此方法並返回結果
2. 如果obj.__str__() 方法不存在,則呼叫obj.__repr__()方法並返回結果
3. 如果obj.__repr__方法不存在,則呼叫object類的__repr__例項方法顯示
<__main__.MyNumber object at xxx>格式的字串
內建函式重寫
__abs__ abs(obj) 函式呼叫
__len__ len(obj) 函式呼叫
__reversed__ reversed(obj) 函式呼叫
__round__ round(obj) 函式呼叫
示例5
# 此示例示意 abs 和len方法的重寫方法
class MyInteger:
def __init__(self, v):
self.data = v
def __repr__(self):
return 'MyInteger(%d)' % self.data
def __abs__(self):
'''此方法用於制定abs(obj) 函式取值時返回的結果'''
if self.data < 0:
# 用-self.data 建立一個新的物件返回回去
t = MyInteger(-self.data)
return t
return MyInteger(self.data)
i1 = MyInteger(-100)
print(i1) # 等同於print(str(i1))
n = abs(i1)
print(n) # MyInteger(100)
i2 = MyInteger(200)
print(abs(i2)) # MyInteger(200)
數值轉換函式重寫
__complex__ coplex(obj) 函式呼叫
__int__ int(obj) 函式呼叫
__float__ float(obj) 函式呼叫
__bool__ bool(obj) 函式呼叫
示例6
# 此示例示意自定義的物件轉為python內鍵的數字型別
class MyNumber:
def __init__(self, v):
self.data = v
def __repr__(self):
return "MyNumber(%d)" % self.data
def __int__(self):
return int(self.data)
n1 = MyNumber(100.5)
n = int(n1) # 自定義型別轉為整數, 出錯!!!
print(n)
布林測試函式重寫
- 格式:
- def bool(self):
…
- def bool(self):
作用:
- 用於bool(obj)函式取值
- 用於if語句真值表達式中
- 用於while語句的值表示式中
說明:
- 1.當自定義類有__bool__(self)方法時,以此方法的返回值作為bool(obj)的返回值
-
- 當不存在__bool__(self)方法時,bool(x)返回__len__(self)方法的返回值是否為零來測試布林值
- 3.當再不存在__len__(self)方法時,則直接返回True
示例7:
# 此示例示意__bool__方法的重寫方法及用法
class MyList:
def __init__(self, iterable=()):
self.data = [x for x in iterable]
def __repr__(self):
return "MyList(%s)" % self.data
def __len__(self):
print("__len__被呼叫")
return len(self.data)
def __bool__(self):
'''此方法用來制定一個bool(x) 返回的規則'''
# 如果沒有任何元素返回False
print("__bool__方法被呼叫")
if len(self.data) == 0:
return False
for x in self.data:
if x:
return True
return False
myl = MyList([1, -2, 3, -4])
# myl = MyList()
print(myl)
print(bool(myl)) # False
print(len(myl))
myl1 = MyList([0, 0.0, False, None])
print(bool(myl1)) # False
myl2 = MyList([0, 1, 2])
print(bool(myl2)) # True