python面向物件--繼承
一. 繼承的概念
生活中的繼承,一般指的是子女繼承父輩的財產。
- 拓展1:經典類或舊式類
不由任意內建型別派生出的類,稱之為經典類。
class 類名:
程式碼
......
- 拓展2:新式類
class 類名(object):
程式碼
Python面向物件的繼承指的是多個類之間的所屬關係,即子類預設繼承父類的所有屬性和方法,具體如下:
# 父類A class A(object): def __init__(self): self.num = 1 def info_print(self): print(self.num) # 子類B class B(A): pass result = B() result.info_print() # 1
在Python中,所有類預設繼承object類,object類是頂級類或基類;其他子類叫做派生類。
二. 單繼承
故事主線:一個煎餅果子老師傅,在煎餅果子界摸爬滾打多年,研發了一套精湛的攤煎餅果子的技術。師父要把這套技術傳授給他的唯一的最得意的徒弟。
分析:徒弟是不是要繼承師父的所有技術?
# 1. 師父類 class Master(object): def __init__(self): self.kongfu = '[古法煎餅果子配方]' def make_cake(self): print(f'運用{self.kongfu}製作煎餅果子') # 2. 徒弟類 class Prentice(Master): pass # 3. 建立物件daqiu daqiu = Prentice() # 4. 物件訪問例項屬性 print(daqiu.kongfu) # 5. 物件呼叫例項方法 daqiu.make_cake()
三. 多繼承
故事推進:daqiu是個愛學習的好孩子,想學習更多的煎餅果子技術,於是,在百度搜索到黑馬程式設計師,報班學習煎餅果子技術。
所謂多繼承意思就是一個類同時繼承了多個父類。
class Master(object): def __init__(self): self.kongfu = '[古法煎餅果子配方]' def make_cake(self): print(f'運用{self.kongfu}製作煎餅果子') # 建立學校類 class School(object): def __init__(self): self.kongfu = '[小馬煎餅果子配方]' def make_cake(self): print(f'運用{self.kongfu}製作煎餅果子') class Prentice(School, Master): pass daqiu = Prentice() print(daqiu.kongfu) daqiu.make_cake()
注意:當一個類有多個父類的時候,預設使用第一個父類的同名屬性和方法。
四. 子類重寫父類同名方法和屬性
故事:daqiu掌握了師父和培訓的技術後,自己潛心鑽研出自己的獨門配方的一套全新的煎餅果子技術。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
class School(object):
def __init__(self):
self.kongfu = '[小馬煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
# 獨創配方
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[獨創煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
daqiu = Prentice()
print(daqiu.kongfu)
daqiu.make_cake()
print(Prentice.__mro__)
子類和父類具有同名屬性和方法,預設使用子類的同名屬性和方法。
五. 子類呼叫父類的同名方法和屬性
故事:很多顧客都希望也能吃到古法和小馬的技術的煎餅果子。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
class School(object):
def __init__(self):
self.kongfu = '[小馬煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[獨創煎餅果子配方]'
def make_cake(self):
# 如果是先呼叫了父類的屬性和方法,父類屬性會覆蓋子類屬性,故在呼叫屬性前,先呼叫自己子類的初始化
self.__init__()
print(f'運用{self.kongfu}製作煎餅果子')
# 呼叫父類方法,但是為保證呼叫到的也是父類的屬性,必須在呼叫方法前呼叫父類的初始化
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
daqiu = Prentice()
daqiu.make_cake()
daqiu.make_master_cake()
daqiu.make_school_cake()
daqiu.make_cake()
六. 多層繼承
故事:N年後,daqiu老了,想要把所有技術傳承給自己的徒弟。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
class School(object):
def __init__(self):
self.kongfu = '[小馬煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[獨創煎餅果子配方]'
def make_cake(self):
self.__init__()
print(f'運用{self.kongfu}製作煎餅果子')
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
# 徒孫類
class Tusun(Prentice):
pass
xiaoqiu = Tusun()
xiaoqiu.make_cake()
xiaoqiu.make_school_cake()
xiaoqiu.make_master_cake()
七. super()呼叫父類方法
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
class School(Master):
def __init__(self):
self.kongfu = '[小馬煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
# 方法2.1
# super(School, self).__init__()
# super(School, self).make_cake()
# 方法2.2
super().__init__()
super().make_cake()
class Prentice(School):
def __init__(self):
self.kongfu = '[獨創煎餅果子技術]'
def make_cake(self):
self.__init__()
print(f'運用{self.kongfu}製作煎餅果子')
# 子類呼叫父類的同名方法和屬性:把父類的同名屬性和方法再次封裝
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
# 一次性呼叫父類的同名屬性和方法
def make_old_cake(self):
# 方法一:程式碼冗餘;父類類名如果變化,這裡程式碼需要頻繁修改
# Master.__init__(self)
# Master.make_cake(self)
# School.__init__(self)
# School.make_cake(self)
# 方法二: super()
# 方法2.1 super(當前類名, self).函式()
# super(Prentice, self).__init__()
# super(Prentice, self).make_cake()
# 方法2.2 super().函式()
super().__init__()
super().make_cake()
daqiu = Prentice()
daqiu.make_old_cake()
注意:使用super() 可以自動查詢父類。呼叫順序遵循
__mro__
類屬性的順序。比較適合單繼承使用。
八. 私有許可權
8.1 定義私有屬性和方法
在Python中,可以為例項屬性和方法設定私有許可權,即設定某個例項屬性或例項方法不繼承給子類。
故事:daqiu把技術傳承給徒弟的同時,不想把自己的錢(2000000個億)繼承給徒弟,這個時候就要為
錢
這個例項屬性設定私有許可權。
設定私有許可權的方法:在屬性名和方法名 前面 加上兩個下劃線 __。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
class School(object):
def __init__(self):
self.kongfu = '[小馬煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[獨創煎餅果子配方]'
# 定義私有屬性
self.__money = 2000000
# 定義私有方法
def __info_print(self):
print(self.kongfu)
print(self.__money)
def make_cake(self):
self.__init__()
print(f'運用{self.kongfu}製作煎餅果子')
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
# 徒孫類
class Tusun(Prentice):
pass
daqiu = Prentice()
# 物件不能訪問私有屬性和私有方法
# print(daqiu.__money)
# daqiu.__info_print()
xiaoqiu = Tusun()
# 子類無法繼承父類的私有屬性和私有方法
# print(xiaoqiu.__money) # 無法訪問例項屬性__money
# xiaoqiu.__info_print()
注意:私有屬性和私有方法只能在類裡面訪問和修改。
8.2 獲取和修改私有屬性值
在Python中,一般定義函式名get_xx
用來獲取私有屬性,定義set_xx
用來修改私有屬性值。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
class School(object):
def __init__(self):
self.kongfu = '[小馬煎餅果子配方]'
def make_cake(self):
print(f'運用{self.kongfu}製作煎餅果子')
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[獨創煎餅果子配方]'
self.__money = 2000000
# 獲取私有屬性
def get_money(self):
return self.__money
# 修改私有屬性
def set_money(self):
self.__money = 500
def __info_print(self):
print(self.kongfu)
print(self.__money)
def make_cake(self):
self.__init__()
print(f'運用{self.kongfu}製作煎餅果子')
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
# 徒孫類
class Tusun(Prentice):
pass
daqiu = Prentice()
xiaoqiu = Tusun()
# 呼叫get_money函式獲取私有屬性money的值
print(xiaoqiu.get_money())
# 呼叫set_money函式修改私有屬性money的值
xiaoqiu.set_money()
print(xiaoqiu.get_money())
九. 總結
-
繼承的特點
- 子類預設擁有父類的所有屬性和方法
- 子類重寫父類同名方法和屬性
- 子類呼叫父類同名方法和屬性
-
super()方法快速呼叫父類方法
-
私有許可權
- 不能繼承給子類的屬性和方法需要新增私有許可權
- 語法
class 類名(): # 私有屬性 __屬性名 = 值 # 私有方法 def __函式名(self): 程式碼