面向?qū)ο缶幊探榻B
面向?qū)ο?/strong>(object-oriented ;簡(jiǎn)稱: OO) 至今還沒(méi)有統(tǒng)一的概念苍碟,我這里把它定義為: 按人們認(rèn)識(shí)客觀世界的系統(tǒng)思維方式,采用基于對(duì)象(實(shí)體)的概念建立模型,模擬客觀世界分析俺亮、設(shè)計(jì)、實(shí)現(xiàn)軟件的辦法斟冕。
面向?qū)ο缶幊?/strong>(Object Oriented Programming-OOP) 是一種解決軟件復(fù)用的設(shè)計(jì)和編程方法。這種方法把軟件系統(tǒng)中相近相似的操作邏輯和操作應(yīng)用數(shù)據(jù)测摔、狀態(tài),以類的型式描述出來(lái),以對(duì)象實(shí)例的形式在軟件系統(tǒng)中復(fù)用,以達(dá)到提高軟件開發(fā)效率的作用浴井。
類和對(duì)象
面向?qū)ο缶幊痰?個(gè)非常重要的概念:類和對(duì)象。
- 對(duì)象是面向?qū)ο缶幊痰暮诵哪呻剩谑褂脤?duì)象的過(guò)程中镰吆,為了將具有共同特征和行為的一組對(duì)象抽象定義,提出了另外一個(gè)新的概念——類躲雅。
- 類就相當(dāng)于制造飛機(jī)時(shí)的圖紙鼎姊,用它來(lái)進(jìn)行創(chuàng)建的飛機(jī)就相當(dāng)于對(duì)象骡和。
類
具有相似內(nèi)部狀態(tài)和運(yùn)動(dòng)規(guī)律的實(shí)體的集合(或統(tǒng)稱為抽象)相赁。具有相同屬性和行為事物的統(tǒng)稱相寇。類是抽象的,在使用的時(shí)候通常會(huì)找到這個(gè)類的一個(gè)具體的存在,使用這個(gè)具體的存在。一個(gè)類可以找到多個(gè)對(duì)象钮科。
對(duì)象
某一個(gè)具體事物的存在 ,在現(xiàn)實(shí)世界中可以是看得見摸得著的唤衫,可以是直接使用的。
類和對(duì)象之間的關(guān)系
類就是創(chuàng)建對(duì)象的模板绵脯。
類的構(gòu)成
類(Class) 由3個(gè)部分構(gòu)成:
- 類的名稱:類名
- 類的屬性:一組數(shù)據(jù)
- 類的方法:允許對(duì)進(jìn)行操作的方法 (行為)
示例:狗類
- 類名:狗(Dog)
- 屬性:品種 佳励、毛色、性別蛆挫、名字赃承、 腿兒的數(shù)量
- 方法(行為/功能):叫 、跑悴侵、咬人瞧剖、吃、搖尾巴
類的抽象
擁有相同(或者類似)屬性和行為的對(duì)象都可以抽像出一個(gè)類可免。
定義類
定義一個(gè)類抓于,格式如下:
class 類名:
方法列表
示例:定義一個(gè)Car類
# 定義類
class Car:
# 方法
def getCarInfo(self):
print('車輪子個(gè)數(shù):%d, 顏色%s'%(self.wheelNum, self.color))
def move(self):
print("車正在移動(dòng)...")
說(shuō)明:
- 定義類時(shí)有2種:新式類和經(jīng)典類,上面的Car為經(jīng)典類浇借,如果是Car(object)則為新式類捉撮;
- 類名的命名規(guī)則按照"大駝峰"。
創(chuàng)建對(duì)象
python中妇垢,可以根據(jù)已經(jīng)定義的類去創(chuàng)建出一個(gè)個(gè)對(duì)象巾遭。
創(chuàng)建對(duì)象的格式為:
對(duì)象名 = 類名()
創(chuàng)建對(duì)象的示例:
# 定義類
class Car:
# 移動(dòng)
def move(self):
print('車在奔跑...')
# 鳴笛
def toot(self):
print("車在鳴笛...嘟嘟..")
# 創(chuàng)建一個(gè)對(duì)象,并用變量BMW來(lái)保存它的引用
BMW = Car()
BMW.color = '黑色'
BMW.wheelNum = 4 #輪子數(shù)量
BMW.move()
BMW.toot()
print(BMW.color)
print(BMW.wheelNum)
總結(jié):
- BMW = Car()修己,這樣就產(chǎn)生了一個(gè)Car的實(shí)例對(duì)象恢总,此時(shí)也可以通過(guò)實(shí)例對(duì)象BMW來(lái)訪問(wèn)屬性或者方法;
- 第一次使用BMW.color = '黑色'表示給BMW這個(gè)對(duì)象添加屬性睬愤,如果后面再次出現(xiàn)BMW.color = xxx表示對(duì)屬性進(jìn)行修改片仿;
- BMW是一個(gè)對(duì)象,它擁有屬性(數(shù)據(jù))和方法(函數(shù))尤辱;
- 當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí)砂豌,就是用一個(gè)模子,來(lái)制造一個(gè)實(shí)物 光督。
__ init __()方法
我們已經(jīng)給BMW這個(gè)對(duì)象添加了2個(gè)屬性阳距,wheelNum(車的輪胎數(shù)量)以及color(車的顏色),試想如果再次創(chuàng)建一個(gè)對(duì)象的話结借,肯定也需要進(jìn)行添加屬性筐摘,顯然這樣做很費(fèi)事,那么有沒(méi)有辦法能夠在創(chuàng)建對(duì)象的時(shí)候,就順便把車這個(gè)對(duì)象的屬性給設(shè)置呢咖熟?我們可以用__ init __()方法實(shí)現(xiàn)這一點(diǎn)圃酵。
使用方式
def 類名:
#初始化函數(shù),用來(lái)完成一些默認(rèn)的設(shè)定
def __init__():
pass
__init __()方法的調(diào)用
# 定義汽車類
class Car:
def __init__(self):
self.wheelNum = 4
self.color = '藍(lán)色'
def move(self):
print('車在跑馍管,目標(biāo):夏威夷')
# 創(chuàng)建對(duì)象
BMW = Car()
print('車的顏色為:%s'%BMW.color)
print('車輪胎數(shù)量為:%d'%BMW.wheelNum)
結(jié)果:
車的顏色為:blue
車輪胎數(shù)量為:4
總結(jié):
當(dāng)創(chuàng)建Car對(duì)象后郭赐,在沒(méi)有調(diào)用__ init__()方法的前提下,BMW就默認(rèn)擁有了2個(gè)屬性wheelNum和color确沸,原因是__ init__()方法是在創(chuàng)建對(duì)象后捌锭,就立刻被默認(rèn)調(diào)用了。
傳參
既然在創(chuàng)建完對(duì)象后__ init__()方法已經(jīng)被默認(rèn)的執(zhí)行了罗捎,那么能否讓對(duì)象在調(diào)用__ init__()方法的時(shí)候傳遞一些參數(shù)呢观谦?如果可以,那怎樣傳遞呢桨菜?
# 定義汽車類
class Car:
def __init__(self, newWheelNum, newColor):
self.wheelNum = newWheelNum
self.color = newColor
def move(self):
print('車在跑坎匿,目標(biāo):夏威夷')
# 創(chuàng)建對(duì)象
BMW = Car(4, 'green')
print('車的顏色為:%s'%BMW.color)
print('車輪子數(shù)量為:%d'%BMW.wheelNum)
結(jié)果:
車的顏色為:green
車輪胎數(shù)量為:4
總結(jié):
- __ init__()方法,在創(chuàng)建一個(gè)對(duì)象時(shí)默認(rèn)被調(diào)用雷激,不需要手動(dòng)調(diào)用替蔬;
- __ init__(self)中,默認(rèn)有1個(gè)參數(shù)名字為self屎暇,如果在創(chuàng)建對(duì)象時(shí)傳遞了2個(gè)實(shí)參承桥,那么__init __(self)中出了self作為第一個(gè)形參外還需要2個(gè)形參,例如__init __(self,x,y)根悼;
- __ init__(self)中的self參數(shù)凶异,不需要開發(fā)者傳遞,python解釋器會(huì)自動(dòng)把當(dāng)前的對(duì)象引用傳遞進(jìn)去挤巡。
self
理解self
如下示例:
# 定義一個(gè)類
class Animal:
# 方法
def __init__(self, name):
self.name = name
def printName(self):
print('名字為:%s'%self.name)
# 定義一個(gè)函數(shù)
def myPrint(animal):
animal.printName()
dog1 = Animal('西西')
myPrint(dog1)
dog2 = Animal('北北')
myPrint(dog2)
運(yùn)行結(jié)果:
名字為:西西
名字為:北北
總結(jié):
- 所謂的self剩彬,可以理解為自己;
- 可以把self當(dāng)做Java中類里面的this指針一樣理解矿卑,就是對(duì)象自身的意思喉恋;
- 某個(gè)對(duì)象調(diào)用其方法時(shí),python解釋器會(huì)把這個(gè)對(duì)象作為第一個(gè)參數(shù)傳遞給self母廷,所以開發(fā)者只需要傳遞后面的參數(shù)即可轻黑。
舉個(gè)例子:老王開槍
人類
- 屬性
- 姓名
- 血量
- 持有的槍
- 方法
- 安子彈
- 安彈夾
- 拿槍(持有搶)
- 開槍
子彈類
- 屬性
- 殺傷力
- 方法
- 傷害敵人(讓敵人掉血)
彈夾類
- 屬性
- 容量(子彈存儲(chǔ)的最大值)
- 當(dāng)前保存的子彈
- 方法
- 保存子彈(安裝子彈的時(shí)候)
- 彈出子彈(開槍的時(shí)候)
槍類
- 屬性
- 彈夾(默認(rèn)沒(méi)有彈夾,需要安裝)
- 方法
- 連接彈夾(保存彈夾)
- 射子彈
人類實(shí)現(xiàn):
class Ren:
def __init__(self,name):
self.name = name
self.xue = 100
self.qiang = None
def __str__(self):
return self.name + "剩余血量為:" + str(self.xue)
def anzidan(self,danjia,zidan):
danjia.baocunzidan(zidan)
def andanjia(self,qiang,danjia):
qiang.lianjiedanjia(danjia)
def naqiang(self,qiang):
self.qiang = qiang
def kaiqiang(self,diren):
self.qiang.she(diren)
def diaoxue(self,shashangli):
self.xue -= shashangli
彈夾類實(shí)現(xiàn):
class Danjia:
def __init__(self, rongliang):
self.rongliang = rongliang
self.rongnaList = []
def __str__(self):
return "彈夾當(dāng)前的子彈數(shù)量為:" + str(len(self.rongnaList)) + "/" + str(self.rongliang)
def baocunzidan(self,zidan):
if len(self.rongnaList) < self.rongliang:
self.rongnaList.append(zidan)
def chuzidan(self):
#判斷當(dāng)前彈夾中是否還有子彈
if len(self.rongnaList) > 0:
#獲取最后壓入到單間中的子彈
zidan = self.rongnaList[-1]
self.rongnaList.pop()
return zidan
else:
return None
子彈類實(shí)現(xiàn):
class Zidan:
def __init__(self,shashangli):
self.shashangli = shashangli
def shanghai(self,diren):
diren.diaoxue(self.shashangli)
槍類實(shí)現(xiàn):
class Qiang:
def __init__(self):
self.danjia = None
def __str__(self):
if self.danjia:
return "槍當(dāng)前有彈夾"
else:
return "槍沒(méi)有彈夾"
def lianjiedanjia(self,danjia):
if not self.danjia:
self.danjia = danjia
def she(self,diren):
zidan = self.danjia.chuzidan()
if zidan:
zidan.shanghai(diren)
else:
print("沒(méi)有子彈了琴昆,放了空槍....")
調(diào)用運(yùn)行:
#創(chuàng)建一個(gè)人對(duì)象
laowang = Ren("老王")
#創(chuàng)建一個(gè)彈夾
danjia = Danjia(20)
print(danjia)
#循環(huán)的方式創(chuàng)建一顆子彈氓鄙,然后讓老王把這顆子彈壓入到彈夾中
i=0
while i<5:
zidan = Zidan(5)
laowang.anzidan(danjia,zidan)
i+=1
#測(cè)試一下,安裝完子彈后业舍,彈夾中的信息
print(danjia)
#創(chuàng)建一個(gè)槍對(duì)象
qiang = Qiang()
print(qiang)
#讓老王抖拦,把彈夾連接到槍中
laowang.andanjia(qiang,danjia)
print(qiang)
#創(chuàng)建一個(gè)敵人
diren = Ren("敵人")
print(diren)
#讓老王拿起槍
laowang.naqiang(qiang)
#老王開槍射敵人
laowang.kaiqiang(diren)
print(diren)
print(danjia)