面向?qū)ο蠡A(chǔ)
目標(biāo)
- 理解面向?qū)ο?/li>
- 類(lèi)和對(duì)象
- 添加和獲取對(duì)象屬性
- 魔法方法
一. 理解面向?qū)ο?/h1>
面向?qū)ο笫且环N抽象化的編程思想,很多編程語(yǔ)言中都有的一種思想。
例如:洗衣服
思考:幾種途徑可以完成洗衣服铆农?
答: 手洗 和 機(jī)洗。
手洗:找盆 - 放水 - 加洗衣粉 - 浸泡 - 搓洗 - 擰干水 - 倒水 - 漂洗N次 - 擰干 - 晾曬。
機(jī)洗:打開(kāi)洗衣機(jī) - 放衣服 - 加洗衣粉 - 按下開(kāi)始按鈕 - 晾曬刃唐。
對(duì)比兩種洗衣服途徑,機(jī)洗更簡(jiǎn)單
思考:機(jī)洗袭景,只需要找到一臺(tái)洗衣機(jī)唁桩,加入簡(jiǎn)單操作就可以完成洗衣服的工作,而不需要關(guān)心洗衣機(jī)內(nèi)部發(fā)生了什么事情耸棒。
總結(jié):面向?qū)ο缶褪菍⒕幊坍?dāng)成是一個(gè)事物荒澡,對(duì)外界來(lái)說(shuō),事物是直接使用的与殃,不用去管他內(nèi)部的情況单山。而編程就是設(shè)置事物能夠做什么事碍现。
二. 類(lèi)和對(duì)象
思考:洗衣機(jī)洗衣服描述過(guò)程中,洗衣機(jī)其實(shí)就是一個(gè)事物米奸,即對(duì)象昼接,洗衣機(jī)對(duì)象哪來(lái)的呢?
答:洗衣機(jī)是由工廠工人制作出來(lái)悴晰。
思考:工廠工人怎么制作出的洗衣機(jī)慢睡?
答:工人根據(jù)設(shè)計(jì)師設(shè)計(jì)的功能圖紙制作洗衣機(jī)。
總結(jié):圖紙 → 洗衣機(jī) → 洗衣服铡溪。
在面向?qū)ο缶幊踢^(guò)程中漂辐,有兩個(gè)重要組成部分:類(lèi)和對(duì)象。
類(lèi)和對(duì)象的關(guān)系:用類(lèi)去創(chuàng)建一個(gè)對(duì)象棕硫。
2.1 理解類(lèi)和對(duì)象
2.1.1 類(lèi)
類(lèi)是對(duì)一系列具有相同特征和行為的事物的統(tǒng)稱(chēng)髓涯,是一個(gè)抽象的概念,不是真實(shí)存在的事物哈扮。
- 特征即是屬性
- 行為即是方法
類(lèi)比如是制造洗衣機(jī)時(shí)要用到的圖紙纬纪,也就是說(shuō)類(lèi)是用來(lái)創(chuàng)建對(duì)象。
2.1.2 對(duì)象
對(duì)象是類(lèi)創(chuàng)建出來(lái)的真實(shí)存在的事物滑肉,例如:洗衣機(jī)包各。
注意:開(kāi)發(fā)中,先有類(lèi)赦邻,再有對(duì)象髓棋。
2.2 面向?qū)ο髮?shí)現(xiàn)方法
2.2.1 定義類(lèi)
Python2中類(lèi)分為:經(jīng)典類(lèi) 和 新式類(lèi)
- 語(yǔ)法
class 類(lèi)名():
代碼
......
注意:類(lèi)名要滿(mǎn)足標(biāo)識(shí)符命名規(guī)則,同時(shí)遵循大駝峰命名習(xí)慣惶洲。
- 體驗(yàn)
class Washer():
def wash(self):
print('我會(huì)洗衣服')
- 拓展:經(jīng)典類(lèi)
不由任意內(nèi)置類(lèi)型派生出的類(lèi)按声,稱(chēng)之為經(jīng)典類(lèi)
class 類(lèi)名:
代碼
......
2.2.2 創(chuàng)建對(duì)象
對(duì)象又名實(shí)例。
- 語(yǔ)法
對(duì)象名 = 類(lèi)名()
- 體驗(yàn)
# 創(chuàng)建對(duì)象
haier1 = Washer()
# <__main__.Washer object at 0x0000018B7B224240>
print(haier1)
# haier對(duì)象調(diào)用實(shí)例方法
haier1.wash()
注意:創(chuàng)建對(duì)象的過(guò)程也叫實(shí)例化對(duì)象恬吕。
2.2.3 self
self指的是調(diào)用該函數(shù)的對(duì)象签则。
# 1. 定義類(lèi)
class Washer():
def wash(self):
print('我會(huì)洗衣服')
# <__main__.Washer object at 0x0000024BA2B34240>
print(self)
# 2. 創(chuàng)建對(duì)象
haier1 = Washer()
# <__main__.Washer object at 0x0000018B7B224240>
print(haier1)
# haier1對(duì)象調(diào)用實(shí)例方法
haier1.wash()
haier2 = Washer()
# <__main__.Washer object at 0x0000022005857EF0>
print(haier2)
注意:打印對(duì)象和self得到的結(jié)果是一致的,都是當(dāng)前對(duì)象的內(nèi)存中存儲(chǔ)地址铐料。
三. 添加和獲取對(duì)象屬性
屬性即是特征渐裂,比如:洗衣機(jī)的寬度、高度钠惩、重量...
對(duì)象屬性既可以在類(lèi)外面添加和獲取柒凉,也能在類(lèi)里面添加和獲取。
3.1 類(lèi)外面添加對(duì)象屬性
- 語(yǔ)法
對(duì)象名.屬性名 = 值
- 體驗(yàn)
haier1.width = 500
haier1.height = 800
3.2 類(lèi)外面獲取對(duì)象屬性
- 語(yǔ)法
對(duì)象名.屬性名
- 體驗(yàn)
print(f'haier1洗衣機(jī)的寬度是{haier1.width}')
print(f'haier1洗衣機(jī)的高度是{haier1.height}')
3.3 類(lèi)里面獲取對(duì)象屬性
- 語(yǔ)法
self.屬性名
- 體驗(yàn)
# 定義類(lèi)
class Washer():
def print_info(self):
# 類(lèi)里面獲取實(shí)例屬性
print(f'haier1洗衣機(jī)的寬度是{self.width}')
print(f'haier1洗衣機(jī)的高度是{self.height}')
# 創(chuàng)建對(duì)象
haier1 = Washer()
# 添加實(shí)例屬性
haier1.width = 500
haier1.height = 800
haier1.print_info()
四. 魔法方法
在Python中篓跛,__xx__()
的函數(shù)叫做魔法方法膝捞,指的是具有特殊功能的函數(shù)。
4.1 __init__()
4.1.1 體驗(yàn)__init__()
思考:洗衣機(jī)的寬度高度是與生俱來(lái)的屬性愧沟,可不可以在生產(chǎn)過(guò)程中就賦予這些屬性呢蔬咬?
答:理應(yīng)如此鲤遥。
==__init__()
方法的作用:初始化對(duì)象。==
class Washer():
# 定義初始化功能的函數(shù)
def __init__(self):
# 添加實(shí)例屬性
self.width = 500
self.height = 800
def print_info(self):
# 類(lèi)里面調(diào)用實(shí)例屬性
print(f'洗衣機(jī)的寬度是{self.width}, 高度是{self.height}')
haier1 = Washer()
haier1.print_info()
注意:
__init__()
方法林艘,在創(chuàng)建一個(gè)對(duì)象時(shí)默認(rèn)被調(diào)用盖奈,不需要手動(dòng)調(diào)用__init__(self)
中的self參數(shù),不需要開(kāi)發(fā)者傳遞狐援,python解釋器會(huì)自動(dòng)把當(dāng)前的對(duì)象引用傳遞過(guò)去钢坦。
4.1.2 帶參數(shù)的__init__()
思考:一個(gè)類(lèi)可以創(chuàng)建多個(gè)對(duì)象,如何對(duì)不同的對(duì)象設(shè)置不同的初始化屬性呢啥酱?
答:傳參數(shù)场钉。
class Washer():
def __init__(self, width, height):
self.width = width
self.height = height
def print_info(self):
print(f'洗衣機(jī)的寬度是{self.width}')
print(f'洗衣機(jī)的高度是{self.height}')
haier1 = Washer(10, 20)
haier1.print_info()
haier2 = Washer(30, 40)
haier2.print_info()
4.2 __str__()
當(dāng)使用print輸出對(duì)象的時(shí)候,默認(rèn)打印對(duì)象的內(nèi)存地址懈涛。如果類(lèi)定義了__str__
方法,那么就會(huì)打印在這個(gè)方法中 return 的數(shù)據(jù)泳猬。
class Washer():
def __init__(self, width, height):
self.width = width
self.height = height
def __str__(self):
return '這是海爾洗衣機(jī)的說(shuō)明書(shū)'
haier1 = Washer(10, 20)
# 這是海爾洗衣機(jī)的說(shuō)明書(shū)
print(haier1)
4.3 __del__()
當(dāng)刪除對(duì)象時(shí)批钠,python解釋器也會(huì)默認(rèn)調(diào)用__del__()
方法。
class Washer():
def __init__(self, width, height):
self.width = width
self.height = height
def __del__(self):
print(f'{self}對(duì)象已經(jīng)被刪除')
haier1 = Washer(10, 20)
# <__main__.Washer object at 0x0000026118223278>對(duì)象已經(jīng)被刪除
del haier1
五. 綜合應(yīng)用
5.1 烤地瓜
5.1.1 需求
需求主線:
-
被烤的時(shí)間和對(duì)應(yīng)的地瓜狀態(tài):
0-3分鐘:生的
3-5分鐘:半生不熟
5-8分鐘:熟的
超過(guò)8分鐘:烤糊了
-
添加的調(diào)料:
用戶(hù)可以按自己的意愿添加調(diào)料
5.1.2 步驟分析
需求涉及一個(gè)事物: 地瓜得封,故案例涉及一個(gè)類(lèi):地瓜類(lèi)埋心。
5.1.2.1 定義類(lèi)
-
地瓜的屬性
- 被烤的時(shí)間
- 地瓜的狀態(tài)
- 添加的調(diào)料
-
地瓜的方法
- 被烤
- 用戶(hù)根據(jù)意愿設(shè)定每次烤地瓜的時(shí)間
- 判斷地瓜被烤的總時(shí)間是在哪個(gè)區(qū)間,修改地瓜狀態(tài)
- 添加調(diào)料
- 用戶(hù)根據(jù)意愿設(shè)定添加的調(diào)料
- 將用戶(hù)添加的調(diào)料存儲(chǔ)
- 被烤
顯示對(duì)象信息
5.1.2.2 創(chuàng)建對(duì)象忙上,調(diào)用相關(guān)實(shí)例方法
5.1.3 代碼實(shí)現(xiàn)
5.1.3.1 定義類(lèi)
- 地瓜屬性
- 定義地瓜初始化屬性拷呆,后期根據(jù)程序推進(jìn)更新實(shí)例屬性
class SweetPotato():
def __init__(self):
# 被烤的時(shí)間
self.cook_time = 0
# 地瓜的狀態(tài)
self.cook_static = '生的'
# 調(diào)料列表
self.condiments = []
5.1.3.2 定義烤地瓜方法
class SweetPotato():
......
def cook(self, time):
"""烤地瓜的方法"""
self.cook_time += time
if 0 <= self.cook_time < 3:
self.cook_static = '生的'
elif 3 <= self.cook_time < 5:
self.cook_static = '半生不熟'
elif 5 <= self.cook_time < 8:
self.cook_static = '熟了'
elif self.cook_time >= 8:
self.cook_static = '烤糊了'
5.1.3.3 書(shū)寫(xiě)str魔法方法,用于輸出對(duì)象狀態(tài)
class SweetPotato():
......
def __str__(self):
return f'這個(gè)地瓜烤了{(lán)self.cook_time}分鐘, 狀態(tài)是{self.cook_static}'
5.1.3.4 創(chuàng)建對(duì)象疫粥,測(cè)試實(shí)例屬性和實(shí)例方法
digua1 = SweetPotato()
print(digua1)
digua1.cook(2)
print(digua1)
5.1.3.5 定義添加調(diào)料方法茬斧,并調(diào)用該實(shí)例方法
class SweetPotato():
......
def add_condiments(self, condiment):
"""添加調(diào)料"""
self.condiments.append(condiment)
def __str__(self):
return f'這個(gè)地瓜烤了{(lán)self.cook_time}分鐘, 狀態(tài)是{self.cook_static}, 添加的調(diào)料有{self.condiments}'
digua1 = SweetPotato()
print(digua1)
digua1.cook(2)
digua1.add_condiments('醬油')
print(digua1)
digua1.cook(2)
digua1.add_condiments('辣椒面兒')
print(digua1)
digua1.cook(2)
print(digua1)
digua1.cook(2)
print(digua1)
5.1.4 代碼總覽
# 定義類(lèi)
class SweetPotato():
def __init__(self):
# 被烤的時(shí)間
self.cook_time = 0
# 地瓜的狀態(tài)
self.cook_static = '生的'
# 調(diào)料列表
self.condiments = []
def cook(self, time):
"""烤地瓜的方法"""
self.cook_time += time
if 0 <= self.cook_time < 3:
self.cook_static = '生的'
elif 3 <= self.cook_time < 5:
self.cook_static = '半生不熟'
elif 5 <= self.cook_time < 8:
self.cook_static = '熟了'
elif self.cook_time >= 8:
self.cook_static = '烤糊了'
def add_condiments(self, condiment):
"""添加調(diào)料"""
self.condiments.append(condiment)
def __str__(self):
return f'這個(gè)地瓜烤了{(lán)self.cook_time}分鐘, 狀態(tài)是{self.cook_static}, 添加的調(diào)料有{self.condiments}'
digua1 = SweetPotato()
print(digua1)
digua1.cook(2)
digua1.add_condiments('醬油')
print(digua1)
digua1.cook(2)
digua1.add_condiments('辣椒面兒')
print(digua1)
digua1.cook(2)
print(digua1)
digua1.cook(2)
print(digua1)
5.2 搬家具
5.2.1 需求
將小于房子剩余面積的家具擺放到房子中
5.2.2 步驟分析
需求涉及兩個(gè)事物:房子 和 家具,故被案例涉及兩個(gè)類(lèi):房子類(lèi) 和 家具類(lèi)梗逮。
5.2.2.1 定義類(lèi)
- 房子類(lèi)
- 實(shí)例屬性
- 房子地理位置
- 房子占地面積
- 房子剩余面積
- 房子內(nèi)家具列表
- 實(shí)例方法
- 容納家具
- 顯示房屋信息
- 實(shí)例屬性
- 家具類(lèi)
- 家具名稱(chēng)
- 家具占地面積
5.2.2.2 創(chuàng)建對(duì)象并調(diào)用相關(guān)方法
5.2.3 代碼實(shí)現(xiàn)
5.2.3.1 定義類(lèi)
- 家具類(lèi)
class Furniture():
def __init__(self, name, area):
# 家具名字
self.name = name
# 家具占地面積
self.area = area
-
房子類(lèi)
class Home():
def __init__(self, address, area):
# 地理位置
self.address = address
# 房屋面積
self.area = area
# 剩余面積
self.free_area = area
# 家具列表
self.furniture = []
def __str__(self):
return f'房子坐落于{self.address}, 占地面積{self.area}, 剩余面積{self.free_area}, 家具有{self.furniture}'
def add_furniture(self, item):
"""容納家具"""
if self.free_area >= item.area:
self.furniture.append(item.name)
# 家具搬入后项秉,房屋剩余面積 = 之前剩余面積 - 該家具面積
self.free_area -= item.area
else:
print('家具太大,剩余面積不足慷彤,無(wú)法容納')
5.2.3.2 創(chuàng)建對(duì)象并調(diào)用實(shí)例屬性和方法
bed = Furniture('雙人床', 6)
jia1 = Home('北京', 1200)
print(jia1)
jia1.add_furniture(bed)
print(jia1)
sofa = Furniture('沙發(fā)', 10)
jia1.add_furniture(sofa)
print(jia1)
ball = Furniture('籃球場(chǎng)', 1500)
jia1.add_furniture(ball)
print(jia1)
六. 總結(jié)
-
面向?qū)ο笾匾M成部分
- 類(lèi)
- 創(chuàng)建類(lèi)
class 類(lèi)名(): 代碼
- 對(duì)象
對(duì)象名 = 類(lèi)名()
- 類(lèi)
-
添加對(duì)象屬性
- 類(lèi)外面
對(duì)象名.屬性名 = 值
- 類(lèi)里面
self.屬性名 = 值
-
獲取對(duì)象屬性
- 類(lèi)外面
對(duì)象名.屬性名
- 類(lèi)里面
self.屬性名
-
魔法方法
-
__init__()
: 初始化 -
__str__()
:輸出對(duì)象信息 -
__del__()
:刪除對(duì)象時(shí)調(diào)用
-
繼承
目標(biāo)
- 繼承的概念
- 單繼承
- 多繼承
- 子類(lèi)重寫(xiě)父類(lèi)的同名屬性和方法
- 子類(lèi)調(diào)用父類(lèi)的同名屬性和方法
- 多層繼承
- super()
- 私有屬性和私有方法
一. 繼承的概念
生活中的繼承娄蔼,一般指的是子女繼承父輩的財(cái)產(chǎn)。
- 拓展1:經(jīng)典類(lèi)或舊式類(lèi)
不由任意內(nèi)置類(lèi)型派生出的類(lèi)底哗,稱(chēng)之為經(jīng)典類(lèi)岁诉。
class 類(lèi)名:
代碼
......
- 拓展2:新式類(lèi)
class 類(lèi)名(object):
代碼
Python面向?qū)ο蟮睦^承指的是多個(gè)類(lèi)之間的所屬關(guān)系,即子類(lèi)默認(rèn)繼承父類(lèi)的所有屬性和方法跋选,具體如下:
# 父類(lèi)A
class A(object):
def __init__(self):
self.num = 1
def info_print(self):
print(self.num)
# 子類(lèi)B
class B(A):
pass
result = B()
result.info_print() # 1
在Python中涕癣,所有類(lèi)默認(rèn)繼承object類(lèi),object類(lèi)是頂級(jí)類(lèi)或基類(lèi)野建;其他子類(lèi)叫做派生類(lèi)属划。
二. 單繼承
故事主線:一個(gè)煎餅果子老師傅恬叹,在煎餅果子界摸爬滾打多年,研發(fā)了一套精湛的攤煎餅果子的技術(shù)同眯。師父要把這套技術(shù)傳授給他的唯一的最得意的徒弟绽昼。
分析:徒弟是不是要繼承師父的所有技術(shù)?
# 1. 師父類(lèi)
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
# 2. 徒弟類(lèi)
class Prentice(Master):
pass
# 3. 創(chuàng)建對(duì)象daqiu
daqiu = Prentice()
# 4. 對(duì)象訪問(wèn)實(shí)例屬性
print(daqiu.kongfu)
# 5. 對(duì)象調(diào)用實(shí)例方法
daqiu.make_cake()
三. 多繼承
故事推進(jìn):daqiu是個(gè)愛(ài)學(xué)習(xí)的好孩子须蜗,想學(xué)習(xí)更多的煎餅果子技術(shù)硅确,于是,在百度搜索到學(xué)習(xí)煎餅果子技術(shù)明肮。
所謂多繼承意思就是一個(gè)類(lèi)同時(shí)繼承了多個(gè)父類(lèi)菱农。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
# 創(chuàng)建學(xué)校類(lèi)
class School(object):
def __init__(self):
self.kongfu = '[新煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
class Prentice(School, Master):
pass
daqiu = Prentice()
print(daqiu.kongfu)
daqiu.make_cake()
注意:當(dāng)一個(gè)類(lèi)有多個(gè)父類(lèi)的時(shí)候,默認(rèn)使用第一個(gè)父類(lèi)的同名屬性和方法柿估。
四. 子類(lèi)重寫(xiě)父類(lèi)同名方法和屬性
故事:daqiu掌握了師父和培訓(xùn)的技術(shù)后循未,自己潛心鉆研出自己的獨(dú)門(mén)配方的一套全新的煎餅果子技術(shù)。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
class School(object):
def __init__(self):
self.kongfu = '[新煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
# 獨(dú)創(chuàng)配方
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[獨(dú)創(chuàng)煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
daqiu = Prentice()
print(daqiu.kongfu)
daqiu.make_cake()
print(Prentice.__mro__)
子類(lèi)和父類(lèi)具有同名屬性和方法秫舌,默認(rèn)使用子類(lèi)的同名屬性和方法的妖。
五. 子類(lèi)調(diào)用父類(lèi)的同名方法和屬性
故事:很多顧客都希望也能吃到古法和新技術(shù)的煎餅果子。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
class School(object):
def __init__(self):
self.kongfu = '[新煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[獨(dú)創(chuàng)煎餅果子配方]'
def make_cake(self):
# 如果是先調(diào)用了父類(lèi)的屬性和方法足陨,父類(lèi)屬性會(huì)覆蓋子類(lèi)屬性嫂粟,故在調(diào)用屬性前,先調(diào)用自己子類(lèi)的初始化
self.__init__()
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
# 調(diào)用父類(lèi)方法墨缘,但是為保證調(diào)用到的也是父類(lèi)的屬性星虹,必須在調(diào)用方法前調(diào)用父類(lèi)的初始化
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老了镊讼,想要把所有技術(shù)傳承給自己的徒弟宽涌。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
class School(object):
def __init__(self):
self.kongfu = '[新煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[獨(dú)創(chuàng)煎餅果子配方]'
def make_cake(self):
self.__init__()
print(f'運(yùn)用{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)
# 徒孫類(lèi)
class Tusun(Prentice):
pass
xiaoqiu = Tusun()
xiaoqiu.make_cake()
xiaoqiu.make_school_cake()
xiaoqiu.make_master_cake()
七. super()調(diào)用父類(lèi)方法
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
class School(Master):
def __init__(self):
self.kongfu = '[新煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{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 = '[獨(dú)創(chuàng)煎餅果子技術(shù)]'
def make_cake(self):
self.__init__()
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
# 子類(lèi)調(diào)用父類(lèi)的同名方法和屬性:把父類(lèi)的同名屬性和方法再次封裝
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
# 一次性調(diào)用父類(lèi)的同名屬性和方法
def make_old_cake(self):
# 方法一:代碼冗余;父類(lèi)類(lèi)名如果變化蝶棋,這里代碼需要頻繁修改
# Master.__init__(self)
# Master.make_cake(self)
# School.__init__(self)
# School.make_cake(self)
# 方法二: super()
# 方法2.1 super(當(dāng)前類(lèi)名, self).函數(shù)()
# super(Prentice, self).__init__()
# super(Prentice, self).make_cake()
# 方法2.2 super().函數(shù)()
super().__init__()
super().make_cake()
daqiu = Prentice()
daqiu.make_old_cake()
注意:使用super() 可以自動(dòng)查找父類(lèi)护糖。調(diào)用順序遵循
__mro__
類(lèi)屬性的順序。比較適合單繼承使用嚼松。
八. 私有權(quán)限
8.1 定義私有屬性和方法
在Python中嫡良,可以為實(shí)例屬性和方法設(shè)置私有權(quán)限,即設(shè)置某個(gè)實(shí)例屬性或?qū)嵗椒ú焕^承給子類(lèi)献酗。
故事:daqiu把技術(shù)傳承給徒弟的同時(shí)寝受,不想把自己的錢(qián)(2000000個(gè)億)繼承給徒弟,這個(gè)時(shí)候就要為
錢(qián)
這個(gè)實(shí)例屬性設(shè)置私有權(quán)限罕偎。
設(shè)置私有權(quán)限的方法:在屬性名和方法名 前面 加上兩個(gè)下劃線 __很澄。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
class School(object):
def __init__(self):
self.kongfu = '[新煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[獨(dú)創(chuàng)煎餅果子配方]'
# 定義私有屬性
self.__money = 2000000
# 定義私有方法
def __info_print(self):
print(self.kongfu)
print(self.__money)
def make_cake(self):
self.__init__()
print(f'運(yùn)用{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)
# 徒孫類(lèi)
class Tusun(Prentice):
pass
daqiu = Prentice()
# 對(duì)象不能訪問(wèn)私有屬性和私有方法
# print(daqiu.__money)
# daqiu.__info_print()
xiaoqiu = Tusun()
# 子類(lèi)無(wú)法繼承父類(lèi)的私有屬性和私有方法
# print(xiaoqiu.__money) # 無(wú)法訪問(wèn)實(shí)例屬性__money
# xiaoqiu.__info_print()
注意:私有屬性和私有方法只能在類(lèi)里面訪問(wèn)和修改。
8.2 獲取和修改私有屬性值
在Python中,一般定義函數(shù)名get_xx
用來(lái)獲取私有屬性甩苛,定義set_xx
用來(lái)修改私有屬性值蹂楣。
class Master(object):
def __init__(self):
self.kongfu = '[古法煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
class School(object):
def __init__(self):
self.kongfu = '[新煎餅果子配方]'
def make_cake(self):
print(f'運(yùn)用{self.kongfu}制作煎餅果子')
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[獨(dú)創(chuàng)煎餅果子配方]'
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'運(yùn)用{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)
# 徒孫類(lèi)
class Tusun(Prentice):
pass
daqiu = Prentice()
xiaoqiu = Tusun()
# 調(diào)用get_money函數(shù)獲取私有屬性money的值
print(xiaoqiu.get_money())
# 調(diào)用set_money函數(shù)修改私有屬性money的值
xiaoqiu.set_money()
print(xiaoqiu.get_money())
九. 總結(jié)
-
繼承的特點(diǎn)
- 子類(lèi)默認(rèn)擁有父類(lèi)的所有屬性和方法
- 子類(lèi)重寫(xiě)父類(lèi)同名方法和屬性
- 子類(lèi)調(diào)用父類(lèi)同名方法和屬性
super()方法快速調(diào)用父類(lèi)方法
-
私有權(quán)限
- 不能繼承給子類(lèi)的屬性和方法需要添加私有權(quán)限
- 語(yǔ)法
class 類(lèi)名(): # 私有屬性 __屬性名 = 值 # 私有方法 def __函數(shù)名(self): 代碼
課程:面向?qū)ο?其他
目標(biāo)
- 面向?qū)ο笕筇匦?/li>
- 類(lèi)屬性和實(shí)例屬性
- 類(lèi)方法和靜態(tài)方法
一. 面向?qū)ο笕筇匦?/h1>
- 封裝
- 將屬性和方法書(shū)寫(xiě)到類(lèi)的里面的操作即為封裝
- 封裝可以為屬性和方法添加私有權(quán)限
- 繼承
- 子類(lèi)默認(rèn)繼承父類(lèi)的所有屬性和方法
- 子類(lèi)可以重寫(xiě)父類(lèi)屬性和方法
- 多態(tài)
- 傳入不同的對(duì)象,產(chǎn)生不同的結(jié)果
二. 多態(tài)
2.1 了解多態(tài)
- 將屬性和方法書(shū)寫(xiě)到類(lèi)的里面的操作即為封裝
- 封裝可以為屬性和方法添加私有權(quán)限
- 子類(lèi)默認(rèn)繼承父類(lèi)的所有屬性和方法
- 子類(lèi)可以重寫(xiě)父類(lèi)屬性和方法
- 傳入不同的對(duì)象,產(chǎn)生不同的結(jié)果
多態(tài)指的是一類(lèi)事物有多種形態(tài)讯蒲,(一個(gè)抽象類(lèi)有多個(gè)子類(lèi)痊土,因而多態(tài)的概念依賴(lài)于繼承)。
- 定義:多態(tài)是一種使用對(duì)象的方式墨林,子類(lèi)重寫(xiě)父類(lèi)方法赁酝,調(diào)用不同子類(lèi)對(duì)象的相同父類(lèi)方法,可以產(chǎn)生不同的執(zhí)行結(jié)果
- 好處:調(diào)用靈活旭等,有了多態(tài)酌呆,更容易編寫(xiě)出通用的代碼,做出通用的編程搔耕,以適應(yīng)需求的不斷變化隙袁!
- 實(shí)現(xiàn)步驟:
- 定義父類(lèi),并提供公共方法
- 定義子類(lèi)弃榨,并重寫(xiě)父類(lèi)方法
- 傳遞子類(lèi)對(duì)象給調(diào)用者藤乙,可以看到不同子類(lèi)執(zhí)行效果不同
2.2 體驗(yàn)多態(tài)
class Dog(object):
def work(self): # 父類(lèi)提供統(tǒng)一的方法,哪怕是空方法
print('指哪打哪...')
class ArmyDog(Dog): # 繼承Dog類(lèi)
def work(self): # 子類(lèi)重寫(xiě)父類(lèi)同名方法
print('追擊敵人...')
class DrugDog(Dog):
def work(self):
print('追查毒品...')
class Person(object):
def work_with_dog(self, dog): # 傳入不同的對(duì)象惭墓,執(zhí)行不同的代碼,即不同的work函數(shù)
dog.work()
ad = ArmyDog()
dd = DrugDog()
daqiu = Person()
daqiu.work_with_dog(ad)
daqiu.work_with_dog(dd)
三. 類(lèi)屬性和實(shí)例屬性
3.1 類(lèi)屬性
3.1.1 設(shè)置和訪問(wèn)類(lèi)屬性
- 類(lèi)屬性就是 類(lèi)對(duì)象 所擁有的屬性而姐,它被 該類(lèi)的所有實(shí)例對(duì)象 所共有腊凶。
- 類(lèi)屬性可以使用 類(lèi)對(duì)象 或 實(shí)例對(duì)象 訪問(wèn)。
class Dog(object):
tooth = 10
wangcai = Dog()
xiaohei = Dog()
print(Dog.tooth) # 10
print(wangcai.tooth) # 10
print(xiaohei.tooth) # 10
類(lèi)屬性的優(yōu)點(diǎn)
- 記錄的某項(xiàng)數(shù)據(jù) 始終保持一致時(shí)拴念,則定義類(lèi)屬性钧萍。
- 實(shí)例屬性 要求 每個(gè)對(duì)象 為其 單獨(dú)開(kāi)辟一份內(nèi)存空間 來(lái)記錄數(shù)據(jù),而 類(lèi)屬性 為全類(lèi)所共有 政鼠,僅占用一份內(nèi)存风瘦,更加節(jié)省內(nèi)存空間。
3.1.2 修改類(lèi)屬性
類(lèi)屬性只能通過(guò)類(lèi)對(duì)象修改公般,不能通過(guò)實(shí)例對(duì)象修改万搔,如果通過(guò)實(shí)例對(duì)象修改類(lèi)屬性,表示的是創(chuàng)建了一個(gè)實(shí)例屬性官帘。
class Dog(object):
tooth = 10
wangcai = Dog()
xiaohei = Dog()
# 修改類(lèi)屬性
Dog.tooth = 12
print(Dog.tooth) # 12
print(wangcai.tooth) # 12
print(xiaohei.tooth) # 12
# 不能通過(guò)對(duì)象修改屬性瞬雹,如果這樣操作,實(shí)則是創(chuàng)建了一個(gè)實(shí)例屬性
wangcai.tooth = 20
print(Dog.tooth) # 12
print(wangcai.tooth) # 20
print(xiaohei.tooth) # 12
3.2 實(shí)例屬性
class Dog(object):
def __init__(self):
self.age = 5
def info_print(self):
print(self.age)
wangcai = Dog()
print(wangcai.age) # 5
# print(Dog.age) # 報(bào)錯(cuò):實(shí)例屬性不能通過(guò)類(lèi)訪問(wèn)
wangcai.info_print() # 5
四. 類(lèi)方法和靜態(tài)方法
4.1 類(lèi)方法
4.1.1 類(lèi)方法特點(diǎn)
- 需要用裝飾器
@classmethod
來(lái)標(biāo)識(shí)其為類(lèi)方法刽虹,對(duì)于類(lèi)方法酗捌,第一個(gè)參數(shù)必須是類(lèi)對(duì)象,一般以cls
作為第一個(gè)參數(shù)。
4.1.2 類(lèi)方法使用場(chǎng)景
- 當(dāng)方法中 需要使用類(lèi)對(duì)象 (如訪問(wèn)私有類(lèi)屬性等)時(shí)胖缤,定義類(lèi)方法
- 類(lèi)方法一般和類(lèi)屬性配合使用
class Dog(object):
__tooth = 10
@classmethod
def get_tooth(cls):
return cls.__tooth
wangcai = Dog()
result = wangcai.get_tooth()
print(result) # 10
4.2 靜態(tài)方法
4.2.1 靜態(tài)方法特點(diǎn)
- 需要通過(guò)裝飾器
@staticmethod
來(lái)進(jìn)行修飾尚镰,靜態(tài)方法既不需要傳遞類(lèi)對(duì)象也不需要傳遞實(shí)例對(duì)象(形參沒(méi)有self/cls)。 - 靜態(tài)方法 也能夠通過(guò) 實(shí)例對(duì)象 和 類(lèi)對(duì)象 去訪問(wèn)哪廓。
4.2.2 靜態(tài)方法使用場(chǎng)景
- 當(dāng)方法中 既不需要使用實(shí)例對(duì)象(如實(shí)例對(duì)象狗唉,實(shí)例屬性),也不需要使用類(lèi)對(duì)象 (如類(lèi)屬性撩独、類(lèi)方法敞曹、創(chuàng)建實(shí)例等)時(shí),定義靜態(tài)方法
- 取消不需要的參數(shù)傳遞综膀,有利于 減少不必要的內(nèi)存占用和性能消耗
class Dog(object):
@staticmethod
def info_print():
print('這是一個(gè)狗類(lèi)澳迫,用于創(chuàng)建狗實(shí)例....')
wangcai = Dog()
# 靜態(tài)方法既可以使用對(duì)象訪問(wèn)又可以使用類(lèi)訪問(wèn)
wangcai.info_print()
Dog.info_print()
五. 總結(jié)
- 面向?qū)ο笕筇匦?
- 封裝
- 繼承
- 多態(tài)
- 類(lèi)屬性
- 歸屬于類(lèi)對(duì)象的屬性,所有對(duì)象共有的屬性
- 實(shí)例屬性
- 類(lèi)方法
@classmethod
def xx():
代碼
- 靜態(tài)方法
@staticmethod
def xx():
代碼