日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

【python系统学习14】类的继承与创新

發布時間:2024/9/5 python 28 如意码农
生活随笔 收集整理的這篇文章主要介紹了 【python系统学习14】类的继承与创新 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄:

  • 目錄:
    [toc]
  • 類的繼承
    • 子類和父類
    • 繼承的寫法
    • 繼承示例
    • 父類可以被無限個子類所繼承
    • 子類實例可調用父類屬性和方法
  • 類的始祖(根類)
    • 根類 - object
    • 實例歸屬判斷 - isinstance()
  • 類的繼承升級版 - 多層繼承
    • 1、啥是多層繼承
    • 2、偽代碼
    • 3、示例代碼
    • 4、多層繼承的好處
  • 類的繼承升級版 - 多重繼承
    • 1、啥是多重繼承
    • 2、就近繼承
    • 3、爸爸近還是爺爺近
    • 4、多重繼承的示例
    • 5、多重繼承的作用
  • 多層繼承和多重繼承
    • 二者的比較
    • 二者的結合
  • 類的創新
    • 創新 - 新增代碼
    • 創新 - 修改(重寫)繼承的內容
    • 優雅的重寫

初中學政治我們就學到過,要繼承中華民族的優秀文化、又要在繼承的基礎上創新。

文化是在不斷繼承和創新中發展的,代碼也是。

我們可以用類特有的繼承方法和拓展創新功能,實現代碼層面的前進。

此節這兩個知識點屬于類中較高階的操作,讓用類寫成的代碼更容易復用、拓展和維護。

類的繼承

說道“繼承”這倆字,你能想到啥?

反正我想到的是,兒子繼承老子的姓氏籍貫特征和遺產等。

放到代碼里,就是子類繼承父類的屬性和方法。

也就是說,通過類的繼承,可以讓子類擁有父類擁有的所有屬性和方法。

這樣,很多基礎代碼不用再重復書寫,就可以直接實現代碼的復用

子類和父類

那之前只了解到類的概念,怎么又多出來一個“子類”和“父類”的區分呢?

我想,這只是統稱。凡是一個類A繼承了另一個類B,那么A就是B的兒子,A就可以統稱為子類,B就可以統稱為父類。

題外話,我現在看這個“類”字看多了,咋看咋像“糞”。。。

繼承的寫法

偽代碼

class A(B): 
  ...子類A的創新定制代碼 # 下詳

注意:

  1. A就是子類,B就是父類
  2. 子類繼承父類時,只需要子類右邊的小括號內部寫父類的類名即可。
  3. 小括號和冒號都是英文格式

繼承示例

還是以老子和兒子的身份,編寫兩段語義化的代碼來了解下:

# 子類Son繼承父類Father的示意
class Father:
  familyName = '郭'
  nativePlace = '河北省'
    
  def language(self):
    print('說中國話')

class Son(Father): # 子類Son繼承父類Father的寫法
  def __init__(self, name):
    self.name = name
  def secondLanguage(self):
    self.language()
    print('學說了英語')

父類可以被無限個子類所繼承

不是一個Son類可以繼承Father,再來十個Son也可以。

class Father:
  familyName = '郭' # 表示姓氏
  nativePlace = '河北省' # 表示籍貫
    
  def language(self): # 表示說母語的能力
    print('說中國話')

class Son(Father): # 子類Son繼承父類Father
  def __init__(self, name):
    self.name = name
  def secondLanguage(self):
    self.language()
    print('學說了英語')

# 父類可以被無限個子類所繼承
class Son2(Father): # 子類Son2繼承父類Father
  def __init__(self):
    print('這里自己想象點Son2特色的代碼吧,我絞盡腦汁了~')
  def characterFn(self):
    self.language()
    pass
class SonN(Father):
  pass

# ...

子類實例可調用父類屬性和方法

子類繼承來的屬性和方法,也會傳遞給子類創建的實例。

這很好理解,子類繼承父類的屬性和方法,相當于子類外掛了父類的屬性和方法。那么子類的實例,也就可以用這些屬性和方法。

看個例子:

class Father:
  familyName = '郭' # 表示姓氏
  nativePlace = '河北省' # 表示籍貫
    
  def language(self): # 表示說母語的能力
    print('說中國話')

class Son(Father): # 子類Son繼承父類Father
  def __init__(self, name):
    self.name = name
  def secondLanguage(self):
    self.language()
    print('學說了英語')

son1 = Son('小菊')
print(son1.name + '姓' + son1.familyName) 
print(son1.name + '籍貫是' + son1.nativePlace)

# 打印結果:
# 小菊姓郭
# 小菊籍貫是河北省

實例化后的對象son1不僅有類Son內部定義的屬性,還有父類Father內部定義的屬性familyName、nativePlace等。

說明子類創建的實例,從子類那間接得到了父類的所有屬性和方法,實例化對象可以隨便運用。

類的始祖(根類)

根類 - object

在上邊類的繼承中,我們協議子類是Son、父類是Father。

那Father還有他的父類嗎?

答案是有的,那就是object

object是所有類的父類,我們將其稱為根類(可理解為類的始祖)。

上述代碼中,class Father:相當于寫成class Father(object)

用isinstance來判斷說明:

實例歸屬判斷 - isinstance()

函數isinstance(),可以用來判斷某個實例是否屬于某個類。

觀察代碼看用法:

# 實例歸屬判斷 isinstance()
class Father:
  pass
class Son(Father):
  pass
class Son2:
  pass

son1 = Son()

print(1,isinstance(son1,Son)) # True
# 說明:子類創建的實例屬于子類(廢話。。。)

print(2,isinstance(son1,Father)) # True
# 說明:子類創建的實例同時也屬于父類

print(3,isinstance(son1,object)) # True
# 說明:說明任何類創建的實例都屬于根類object

print(4,isinstance(son1,(Son,Father))) # True
# 說明:son1屬于Son的實例、也屬于Father的實例

print(4,isinstance(son1,(Father,Son))) # True
# 說明:son1屬于Son的實例、也屬于Father的實例

print(5,isinstance(son1,Son2)) # False
# 說明:son1不是Son2的實例。A子類創建的實例不屬于C子類

print(6,isinstance(Son,Father)) # False
# 說明:這倆都是類所以報錯。

print(7,isinstance(Son,object)) # True
# 說明:可以說明Son(任何類)是根類object的實例

print(8,isinstance(Father,object)) # True
# 說明:可以說明Father(任何類)是根類object的實例

print(9,isinstance(Son,(Father,object))) # True
# 說明:Son不屬于Father的實例,但他是根類object的實例

總結用法:

# 第一種(偽代碼)
isinstance(實例名, 類名)

# 第二種(偽代碼)
isinstance(實例名, (類名1, 類名2...)) # 第二個參數是類名組成的元祖類型數據。

返回結果:

布爾值。True或False。

判斷第一個參數是第二個參數的實例、或者判斷第一個參數屬于第二個參數中某個類的實例,則返回True。反之返回False。

總結知識點:

1. 子類創建的實例,同屬于該子類的父類。
2. 父類創建的實例,與他的子類沒關系。
3. 所有類,都屬于根類object的實例。
4. 所有實例,都屬于根類object的實例。
5. 子類A創建的實例,不屬于其他C等子類的實例。

具體值與基本類型的歸屬判斷:
看代碼總結知識點吧

print(isinstance(1,int)) # True
# 判斷1是否為整數類的實例,實例1是整數類的實例

print(isinstance(1,str)) # False
# 實例1不是字符串類的實例

print(isinstance(1,(int,str))) # True
# 實例1是整數類的實例

print(isinstance(1,object)) # True
# 實例1是根類object的實例

類的繼承升級版 - 多層繼承

1、啥是多層繼承

繼承不僅可以發生在兩個層級之間(即父類-子類),還可以有父類的父類、父類的父類的父類……

比如三個類A、B、C。A是爺爺、B是爸爸、C是兒子。我們可以B繼承A、C再繼承B。后邊再可以有孫子D、D再繼承C等等。。。

這樣一層一層,層層向上/向下繼承,就是多層繼承

一“碼”以蔽之:

2、偽代碼

class B(A):
  ...
class C(B):
  ...
class D(C):
  ... 
class...

3、示例代碼

# 多層繼承
class Grand:
  familyName = '郭' # 表示姓氏
class Father(Grand):
  fatherName = '明爸'
 
class Son(Father):
  def __init__(self,name):
    self.sonName = name
    print(self.fatherName) # 子類拿到父類的屬性
    print(self.familyName+self.sonName) # 子類拿到父類的父類 的屬性

son = Son('小明')
# 執行后打印
# 明爸
# 郭小明

print(son.fatherName) # 實例拿到父類的屬性
print(son.familyName + son.sonName) # 實例拿到父類的父類 的屬性
# 執行后打印
# 明爸
# 郭小明

只要你愿意,你可以繼續拓展上面的例子,或往上(爺爺的爸爸),或往下(兒子的兒子)。所以,多層繼承又屬于繼承的深度拓展。

4、多層繼承的好處

從上邊代碼就能看出功能,Son類創建的實例不僅可以調用Father的屬性和方法、還能調用爺爺Grand類的屬性和方法。

結論就是:子類創建的實例可調用所有層級父類的屬性和方法。

類的繼承升級版 - 多重繼承

1、啥是多重繼承

一個類同時繼承多個類,就叫多重繼承。就好像同時擁有好幾個爸爸。

# 偽代碼:
class A(B,C,D):

2、就近繼承

括號里B、C和D的順序是有講究的。和子類更相關的父類會放在更左側。

也就是血緣關系越深的爸爸,在括號里的順序越靠前。

既然跟B爸爸最親,所以兒子A類創建的實例在調用屬性和方法時,會優先在最左側的父類B中找,找不到才會去第二左側的父類C中找,依舊找不到才會最后去父類D中找。有點“就近原則”的意思,當然,如果最后幾個類中都沒找到,

3、爸爸近還是爺爺近

A類創建的實例調用屬性和方法時,先在直接爸爸A類中找,還是先在爸爸繼承的最親近的B類中找?(這里A相當于A實例的爸爸,B相當于A實例的爺爺。)

class Grand:
  name = '親爺爺'
class Father(Grand):
  name = '爸爸'

son = Father()
# 說明先在直接爸爸中找屬性
print(son.name) # 爸爸

總結:先在直接爸爸中找屬性。找不到,再去爸爸繼承的爺爺類們找。

4、多重繼承的示例

用一段大型家庭倫理來寫一個多重繼承。

其中,身份情況如下:

代表的身份 倫理身份 對應下邊示例中的變量
實例 兒子 son
A類 爸爸 Father
B類 親爺爺 爺爺Grand2在三個爺爺中排行老二
C類 大爺爺 Grand1
D類 小爺爺 Grand3
# 多重繼承
class Grand1:
  name = '大爺爺'
  grand1 = '我是老大'
  age = 60
class Grand2:
  name = '親爺爺'
  grand2 = '我是老二'
  age = 59
class Grand3:
  name = '小爺爺'
  grand3 = '我是老三'
  age = 58
  hobby = '只有小爺爺有hobby屬性'
class Father(Grand2, Grand1, Grand3):
  name = '爸爸'
  father = '我是爸爸'

son = Father()

# 說明先在直接爸爸中找屬性
print(son.name) # 爸爸

# 以下說明實例可以拿到其他重繼承類內部的屬性
print(son.father) # 我是爸爸
print(son.grand1) # 我是老大
print(son.grand2) # 我是老二
print(son.grand3) # 我是老三

# 以下說明多重繼承的就近原則 - 就近取最近的爺爺的屬性
print(son.age) # 59

# 以下說明前幾重父類都沒有,取第一個有該屬性的父類,哪怕這個父類時最后一重繼承的
print(son.hobby) # 只有小爺爺有hobby屬性

5、多重繼承的作用

這自然不用說,子類創建的實例可調用所有重父類的屬性和方法。

多層繼承和多重繼承

二者的比較

來一個比較表格吧

名稱 多層繼承 多重繼承
寫法 class B(A):
...
class C(B):
...
class A(B, C, D):
...
例子 孫子繼承兒子、兒子繼承爸爸、爸爸繼承爺爺 爸爸繼承爺爺、大爺爺、小爺爺
特點 類在縱向上深度拓展 類在橫向上寬度擴展
作用 子類創建的實例,可調用所有層級的父類的屬性和方法 同多層繼承,可以調用所有。不過遵循就近原則。優先考慮靠近子類的父類的屬性和方法。

二者的結合

多層繼承和多重繼承二者單用都是一條線,但是將二者結合起來,那就是個十字啊!

實例兒子依次繼承了爸爸、爺爺、大爺爺、小爺爺、爺爺的爸爸這幾個類的所有屬性和方法。簡直就是超級富二代啊~

多層繼承和多重繼承的結合,讓繼承的類擁有更多的屬性和方法,且能更靈活地調用。進而,繼承的力量也得以放大了很多倍。

一碼以蔽之

# 多層繼承和多重繼承結合
class GrandFather:
  name = '爺爺的爸爸-太爺爺'
  age = 102
class Grand1:
  name = '大爺爺'
class Grand2(GrandFather): # 多層繼承1
  name = '親爺爺'
class Grand3:
  name = '小爺爺(又名二爺爺)'
  age = 62
class Father(Grand2, Grand1, Grand3): # 多層繼承2 + 多重繼承
  name = '爸爸'

son = Father() # 實例兒子
print(son.name) # 爸爸
print(son.age) # 102

上例中,son.age這段打印的 102說明,雖然Grand2中沒有,但是Grand2的多層繼承GrandFather中有,所以順序是先從多層中找,最后才考慮多重繼承的Grand3中的變量。

總結:多重繼承中,若某父類還有父類的話,會先按照多層繼承的順序,縱向往上找到頂。若到頂還沒有,則再繼續向右擴展尋找多重的繼承。

類的創新

我們可以在繼承父類代碼的基礎上,再書寫子類自己更具自我特色的代碼。這就是子類的創新部分了。

比如下邊代碼中,兒子的姓就是繼承父親的。兒子的名字就是自己創新的部分。兒子籍貫是繼承父類后生下來就有的,但是以后自己跑到北京、杭州居住,那就是自己創新的部分。

創新 - 新增代碼

# 子類繼承父類并做自我創新
class Father:
  familyName = '郭' # 姓氏
  nativePlace = '河北省' # 籍貫
  def language(self):
    print('%s家,母語說中國話' %(self.familyName))

class Son(Father): # 子類Son繼承父類Father
  def __init__(self, name, presentAddress):
    self.name = name # 子類創新自己的屬性name
    self.presentAddress = presentAddress # 子類創新自己的屬性presentAddress

  def secondLanguage(self, languageName): # 子類創新自己的方法secondLanguage
    self.language()
    print('%s單獨學說了%s' %(self.name, languageName))
    
  def resume(self): # 子類創新自己的方法resume
    print('%s姓%s,籍貫是%s。現居住在%s' %(self.name, self.familyName,self.nativePlace, self.presentAddress))

# 子類的第一個實例
son1 = Son('小菊', '北京')
son1.secondLanguage('英語')
son1.resume()

# 子類的第二個實例
son2 = Son('小鋒', '杭州')
son2.secondLanguage('韓語')
son2.resume()

# 實例既可以用子類的屬性和方法,也可以調用父類的屬性和方法
print(son1.familyName)
print(son1.nativePlace)

上述代碼中,

子類內部用的self.language()、以及這個language方法內部用的屬性familyName、子類自己方法resume中用的self.nativePlace等都是繼承自父類Father的。

這就是繼承的部分。

Son類中的self.name、self.presentAddress 是屬于子類新增的屬于自己的屬性、

self.secondLanguage、self.resume 是屬于子類新增的屬于自己的方法。這就是創新的部分。

好吧,我承認這是一句多余的不行的廢話

創新 - 修改(重寫)繼承的內容

在繼承的基礎上可以做新加代碼,甚至可以重寫(修改)繼承來的屬性和方法。

重寫代碼: 是在子類中,對父類代碼的修改。

還是用代碼來說明問題,在上邊代碼的基礎上,我們想一段情景劇:

Father類現在有一個二兒子Son2,他從小生下來被過繼給了日本的親叔叔。

因為叔叔和爸爸同姓,所以繼承的屬性“familyName”不用管,還是姓“郭”。但是到了日本后上戶口就是日本的籍貫了,所以“nativePlace”得修改重寫。

另外雖然是爸爸的兒子(繼承自Father),但是因為在日本長大,所以母語變成說日語了。于是我們重寫了繼承來自爸爸類的方法“language”。如下

class Father:
  familyName = '郭'
  nativePlace = '河北省'
  def language(self):
    print('%s家,母語說中國話' %(self.familyName))

class Son(Father): # 子類Son繼承父類Father
  # ...代碼同上一段里的

class Son2(Father): # 繼承父類Father,不過被過繼給叔叔的二兒子類Son2
  languageTxt = '日語' # 自己的屬性,屬新增的創新
  nativePlace = '北海道' # 修改的屬性,屬重寫的創新
  def language(self): # 修改的方法,屬重寫的創新
    print('我的母語說:', self.languageTxt) # 里邊的代碼有自己定制的內容,屬于重寫。
  
son2 = Son2()
son2.language()
# 我的母語說: 日語

可見,重寫父類的屬性和方法,只要在子類中重新定義同名的變量,并做自己的定制代碼即可。

但是,直接在Son2里這么寫,Father會不會傷心呢?

到底是自己生的兒子,給了別人后就這么迫不及待、直接的修改,爸爸的心,痛啊!

所以,重寫代碼按照上邊這么寫,他粗魯了。那有什么優雅的重寫嗎?

優雅的重寫

# 優雅的重寫
class Father:
  familyName = '郭'
  nativePlace = '河北省'
  def language(self, languageTxt = '中國話'): # 需要父類的這個方法協助修改
    print('%s家,母語說%s' %(self.familyName, languageTxt)) 

class Son2(Father):
  languageTxt = '日語'
  nativePlace = '北海道'
  def language(self): # 依舊重寫方法
    Father.language(self, self.languageTxt) # 不過里邊的代碼不再是粗魯的直接修改為自己的內容,而是調用父類的方法,但是傳不同的參數。
  
son2 = Son2()
son2.language()
# 郭家,母語說日語

上邊代碼,依舊重寫方法。不過里邊的代碼不再是粗魯的直接修改為自己的內容,而是調用父類的方法,但是傳不同的參數。


總結:所謂創新,在復用代碼的基礎上,又能滿足個性化的需求。

本文使用 mdnice 排版

總結

以上是生活随笔為你收集整理的【python系统学习14】类的继承与创新的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。