程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

(十)python之多態

編輯:Python

一、面向對象三大特征

面向對象編程的三大特征:封裝,集成,多態

  • 封裝:客官的事物封裝成類(將數據和方法放在一個類中就構成了封裝)
  • 繼承:在python中一個類可以集成於另一個類也可以繼承多個類,被繼承的類叫父類(或者叫基類,base class),繼承的類叫子類
  • 多態(polymorphism):指的是一類事物有多種形態,一個抽象類有多個子類(因而多態的概念依賴於繼承),不同的子類對象調用相同的方法,產生不同的執行結果,多態可以增加代碼的靈活度

二、多繼承(拓展)

(1)Demo類同時繼承A類和B類,然後Demo類實例化一個對象d,這個對象d可以調用A類和B類裡面的屬性和方法。

class A:
a_attr1 = 100
def func_a(self):
print('------func_a--------')
class B:
b_attr1 = 999
def func_b(self):
print('------func_b--------')
class Demo(A, B):
pass
d = Demo()
# 調用父類A的屬性和方法
print(d.a_attr1)
d.func_a()
# 調用父類B的屬性和方法
print(d.b_attr1)
d.func_b()
# 打印結果
100
------func_a--------
999
------func_b--------

(2) 如果繼承了2個類,調用兩個父類中同名的方法和屬性會怎麼取值呢?

答:就近原則,他先找括號裡面左邊這個類,左邊這個類找到了就不會再去找右邊這個類,左邊的類如果找不到就去右邊這個類找。

注意:如果demo這個類自己有這個方法,就不會再去父類裡面找,如果demo這個類沒有,才會去父類裡面去找。

class A:
a_attr1 = 100
attr = 10
def func_a(self):
print('----funca——————')
def work(self):
print('----funca——work————')
class B:
b_attr1 = 999
attr = 99999
def func_b(self):
print('----funcb——————')
def work(self):
print('----funcb——work————')
class Demo(A, B):
pass
d = Demo()
# 調用兩個父類中同名的方法和屬性
print(d.attr)
# 打印結果
10

(3)只讀屬性(property) 

方法名上面加了@property之後,不再是方法名,而是屬性名稱

class B:
b_attr1 = 999
attr = 99999
def func_b(self):
print('----funcb——————')
def work(self):
print('----funcb——work————')
class Demo(A, B):
def work(self):
print('demo---work')
@property # 定義只讀屬性
def battr(self):
return B.attr
d = Demo()
# 只讀屬性
print(d.battr)
# 打印結果
99999

(4)多繼承的應用思想

"""
定義一個api測試的用例類
1、用例數據處理
2、接口請求
3、響應數據提取
3、斷言
"""
class HandleData:
pass
class RequestApi:
pass
class BaseTest(HandleData, RequestApi):
pass

三、多態

實現多態的步驟:

  • 1、定義一個父類(Base),實現某個方法(比如:run)
  • 2、定義多個子類,在子類中重寫父類的方法(run),每個子類run方法實現不同的功能
  • 3、假設我們定義了一個函數,需要一個Base類型的對象的參數,那麼調用函數的時候,傳入Base類不同的子類對象,那麼這個函數就會執行不同的功能,這就是多態的體現。

還是不懂多態是啥意思嗎?沒關系,我們上一段代碼就明白了。

一個父類,他具有多個子類,不同的子類在調用相同的方法,執行的時候產生不同的形態,這個叫多態。

class Animal(object):
"""動物類"""
def func(self):
print('動物發出了聲音')
class Cat(Animal):
"""貓類"""
def func(self):
print('喵 喵 喵')
class Dog(Animal):
"""狗類"""
def func(self):
print('汪 汪 汪 ')
class Hero:
def func(self):
print('這個是英雄類的方法,不是動物類的對象')
def work01(musen: Animal):
musen.func()
work01(Hero())

多態的意義:

  • 對於一個變量,我們只需要知道他是Animal類型,無需確切地知道它的子類型,就可以放心地調用run()方法(調用方只管調用,不管細節)
  • 當需要新增功能,只需要新增一個Animal的子類實現run()方法,就可以在原來的基礎上進行功能擴展,這就是著名的“開放封閉”原則:​​​​​​​

“開放封閉”原則:

  • 對擴展開放:允許新增Animal子類
  • 對修改封閉:不需要修改依賴Animal類型的run()等函數

注意點:Python中函數的參數是沒有類型限制的,所以多態在python中的體現並不是很嚴謹。多態的概念是應用於Java和C#這一類強類型語言中,而Python崇尚“鴨子類型”。

class Animal(object):
"""動物類"""
def func(self):
print('動物發出了聲音')
class Cat(Animal):
"""貓類"""
def func(self):
print('喵 喵 喵')
class Dog(Animal):
"""狗類"""
def func(self):
print('汪 汪 汪 ')
class Hero:
def func(self):
print('這個是英雄類的方法,不是動物類的對象')
def work01(musen: Animal):
musen.func()
work01(Hero())

四、鴨子類型

  • 鴨子類型概念:他並不要求嚴格的繼承體系,關注的不是對象的類型本身,而是它是否具有要調用的方法(行為)
  • 鴨子類型在python中的案例:
    ​​​​​​​
    內置函數iter:參數可以是實現迭代協議(__iter__方法)的任何類型的對象。
    ​​​​​​​
"""
"""
鴨子類型概念:它並不要求嚴格的繼承體系,關注的不是對象的類型,而是它是否具有要調用的方法(行為)。
鴨子類型在python中的案例:
內置函數iter:參數可以是實現迭代協議(`__iter__`方法)的任何類型的對象
"""
li = [11, 22, 33, 44]
s = '1212124'
class MyTest:
def __iter__(self):
return (i for i in range(10))
def __len__(self):
return 10
li1 = iter(li) # 內置函數iter將可迭代對象轉換為迭代器,,本質上是調用對象的__iter__
s1 = iter(s) # 內置函數iter將可迭代對象轉換為迭代器,,本質上是調用對象的__iter__
m = MyTest()
m1 = iter(m)
# 內置函數len獲取數據的長度,本質上是調用對象的__len__
print(len(m))


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved