面向?qū)ο蟮木幊趟枷氲陌l(fā)展歷程
我理解的面向過程與面向?qū)ο?/b>
自從學(xué)習(xí)python以來,以前所接觸的代碼是根據(jù)實(shí)際的案例胧奔,按照過程皇拣,像踩西瓜皮那樣,從上到下的按照思路來走逻翁,這樣的編程思路只適合于中小型的項(xiàng)目案例開發(fā)饥努,如果面對較多的數(shù)據(jù)以及變量,就有些力不從心了八回,會產(chǎn)生很冗余的代碼量酷愧,但是面向?qū)ο缶筒煌耍m說面向?qū)ο筝^面向過程來說缠诅,相對復(fù)雜溶浴,但是面向?qū)ο髮τ诖a模塊化來說是明顯高于面向過程的,而且因?yàn)槠滹@著特點(diǎn)在擴(kuò)展功能以及維護(hù)上是明顯優(yōu)于面向過程的管引,所以說二者沒有好壞之分士败,只有合不合適,對于我們來講更是會不會褥伴,熟練不熟練的問題了谅将。所以學(xué)好面向?qū)ο蟮木幊趟悸芬彩呛苡斜匾摹?/p>
面向?qū)ο缶幊痰幕靖拍?/b>
類:
類是一類事物的總稱,這類事物有著或多或少的相似之處噩翠,稱為特征戏自,類是一個概念。
對象:
對象就是實(shí)際存在的事物伤锚,世間萬物都是對象擅笔,是類型表示的具體的實(shí)際存在一個實(shí)例
類與對象的關(guān)系:
類就是一個模板志衣,模板里可以包含多個函數(shù),函數(shù)里實(shí)現(xiàn)一些功能猛们。
對象則是根據(jù)模板創(chuàng)建的實(shí)例念脯,通過實(shí)例對象可以執(zhí)行類中的函數(shù)
怎樣定義一個類:
組成部分包括,類型名稱弯淘,屬性绿店,方法。通過關(guān)鍵字class定義類型庐橙,通過_init_()函數(shù)假勿,來初始化累的屬性數(shù)據(jù),通過普通的函數(shù)來實(shí)現(xiàn)類的行為方法(ps:類中的函數(shù)第一個參數(shù)必須是self)态鳖。
怎樣創(chuàng)建一個對象:
可以直接通過類的名稱转培,來創(chuàng)建對象。
怎樣使用對象的屬性:
對象的屬性浆竭,可以直接通過對象的引用變量.屬性名稱來使用浸须。
再怎樣使用對象的方法(調(diào)用函數(shù)):
對象的方法,可以直接通過對象的引用變量.方法名稱()來調(diào)用方法
創(chuàng)建對象的過程:
首先邦泄,調(diào)用對象的_new_()函數(shù)申請內(nèi)存删窒,創(chuàng)建對象。其次顺囊,給創(chuàng)建好的對象肌索,初始化對象的數(shù)據(jù),會自動調(diào)用_init_()函數(shù)特碳,給對象的屬性賦值驶社。
創(chuàng)建好的對象,賦值給了一個變量测萎,變量是什么類型?存放的是什么數(shù)據(jù)届巩?
對象賦值給一個變量硅瞧,變量存放的是對象的存儲地址數(shù)據(jù),存放的是類類型
面向?qū)ο蟮奶卣?--封裝的意義和操作過程
什么是封裝
從字面上來講就是把事物裝起來而且封上恕汇,就像在收拾東西的時候把一些零碎的腕唧,彼此之間有些關(guān)聯(lián)的東西放在一個收納箱里,比如說把衣服放進(jìn)衣柜瘾英,無論上衣下衣枣接,春裝夏裝,他們都是屬于一個“衣服”的類型缺谴,再比如拖鞋和運(yùn)動鞋都放在鞋柜里但惶,所以說,面向?qū)ο蟮姆庋b就是把一些相關(guān)聯(lián)而又零散的數(shù)據(jù)封裝在一個類型中。比如和商品類型有關(guān)的會有商品價格膀曾,商品種類县爬,商品的庫存等等等等。
#定義了一個商品類型添谊,封裝和商品有關(guān)系的數(shù)據(jù)
class Goods:
? ? ? ? def __init__(self,name, price, stock):
? ? ? ? ? ? ? ? ? ?self.name = name
? ? ? ? ? ? ? ? ? ?self.price = price
? ? ? ? ? ? ? ? ? ?self.stock = stock
怎么封裝
屬性私有化:一些對象的屬性往往不是對所有人都能夠訪問的财喳,就像生活中不能直接把手伸進(jìn)人家的口袋,小偷是未經(jīng)允許的偷盜行為你是不知情的斩狱,而乞丐是你允許的耳高,然后把錢給人家的行為,所以屬性的私有化所踊,不能夠被外界直接訪問泌枪。
所以,不帶下劃線的屬性可以直接訪問污筷,就像推門而入工闺。約定以一個下劃線開頭的變量,是私有變量外界可以訪問但是不能直接訪問瓣蛀,需要先敲門然后在進(jìn)入陆蟆。要求兩個下劃線開頭的屬性,表示當(dāng)前的私有屬性外界不能訪問惋增,門里是鎖著的叠殷,不僅要敲門,還需要得到屋里人的同意給你開門诈皿,你才能進(jìn)林束。
封裝實(shí)現(xiàn)的步驟
1.完成一個類的定義
2.所有屬性私有化
3.給每個屬性提供set/get方法
具體案例
1. 類型的定義:零散數(shù)據(jù)包含在一個類中,封裝
class Users:
? ? ? ? def __init__(self, name):
? ? ? ? ? ? self.name = name
u = Users("tom")
print(u.name)
u.name = "jerry"
print(u.name)
--------------------------------------
2.屬性私有化稽亏,提供set/get函數(shù):封裝進(jìn)階
class Person:
? ? ? ? def __init__(self, name):
? ? ? ? ? ? self.__name = name? # 屬性私有化
? ? ? ? def set_name(self, name):
? ? ? ? ? ? self.__name = name
? ? ? ? def get_name(self):
? ? ? ? ? ? return self.__name
p = Person("shuke")
print(p.get_name())
p.set_name("beita")
print(p.get_name())
--------------------------------------
3.添加@property和@method.setter壶冒,隱藏set/get函數(shù):高級封裝
class Computer:
? ? ? ? def __init__(self, name):
? ? ? ? ? ? self.__name = name
? ? ? ? @property #給獲取值的方法,添加@property
? ? ? ? def get_name(self):
? ? ? ? ? ? return self.__name
? ? ? ? @get_name.setter
? ? ? ? def set_name(self, name):
? ? ? ? ? ? self.__name = name
c = Computer("Alienware")
print(c.get_name)
c.set_name = "HP"
print(c.get_name)
--------------------------------------
4.擴(kuò)展:同一個類中截歉,出現(xiàn)了相同名稱但是參數(shù)不同的函數(shù):方法重載
class Animal(object):
? ? ? ? def __init__(self, name, age):
? ? ? ? ? ? # 將屬性私有化胖腾,外界不能訪問了
? ? ? ? ? ? self.__name = name
? ? ? ? ? ? self.__age = age
? ? ? ? # 在同一個類中,出現(xiàn)了兩個或者兩個以上同名函數(shù)/方法:方法重載
? ? ? ? @property
? ? ? ? def name(self): # name()
? ? ? ? ? ? return self.__name
? ? ? ? ?@name.setter
? ? ? ? ?def name(self, n):# name("tom")
? ? ? ? ? ? ?self.__name = n
? ? ? ? ? def age(self):
? ? ? ? ? ? ? ? return self.__age
? ? ? ? ? def age(self, a):
? ? ? ? ? ? ? ? ?if (a >= 0) and (a <= 20):
? ? ? ? ? ? ? ? ? ? ? ?self.__age = a
? ? ? ? ? ? ? ? ?else:
? ? ? ? ? ? ? ? ? ? ? ?print("年齡不合法...")
a = Animal("cat", 18)
a.name = "tom"# 設(shè)置值
print(a.name)#獲取值
a.age = 22# 設(shè)置值
print(a.age)# 獲取值
# print(a.age())
# a.age(20)
# print(a.age())
面向?qū)ο蟮奶卣?--繼承的意義和操作過程
我所理解的繼承
我所理解的繼承瘪松,就像字面上的那樣的意思的繼承咸作,兒子繼承父親的東西,比如宵睦,票子记罚、車子、房子壳嚎,在編程中的繼承也是這樣的子類會繼承父類的公共的屬性和方法桐智,從而達(dá)到代碼重復(fù)使用的目的末早,之所以是說公共的,是因?yàn)橐恍┧接械氖遣荒軌蚶^承來的酵使,就像兒子不能繼承老爸的回憶和一些想法荐吉,這是不能夠給別的的,屬于自身私有的口渔,就算是親兒子那也給不了啊样屠,所以這也是繼承的特性的一部分。
在python中缺脉,一個類型不但可以被繼承給多個類型(相當(dāng)于一個爸爸有好幾個孩子這是允許的)而且一個類型還可以同時繼承多個類型的公開的屬性和方法痪欲,就像一個人有很多的王叔叔那樣,強(qiáng)行解釋一波吧攻礼,业踢,周末,媽媽讓王叔叔們帶著出去玩礁扮,肯定先要跟第一個來接你的王叔叔一起去知举,坐著他的車子,花著他的票子太伊,但路上他不跟你講他跟媽媽的一些回憶雇锡,這是屬于王叔叔自己的私人的,不能告訴你的僚焦。所以反映在程序中一個類型可以繼承多個類型公共的屬性和方法锰提,是公共的。而且按照繼承的先后順序優(yōu)先調(diào)用芳悲,一號王叔叔和十八號王叔叔都在等著立肘,但是一號先來的,所以理應(yīng)跟著一號王叔叔去玩名扛,另一方面谅年,如果本身就可以單獨(dú)去玩,不需要調(diào)用一群王叔叔肮韧,那就自己一個人去踢故,反映在程序中叫做方法的重寫!
為什么要繼承
達(dá)到代碼的重復(fù)使用的目的惹苗。
繼承的語法
class 類型(被繼承的類型):
? ? ? ? ? ?pass
繼承中出現(xiàn)的術(shù)語
父類:被繼承的類,也稱為基類耸峭、超類
子類:當(dāng)前類桩蓉,也稱為派生類
子類繼承父類,體現(xiàn)的時A is a B的關(guān)系
子類繼承父類劳闹,就可以使用父類中所有的公開的屬性和方法
繼承鏈
A繼承B院究,B繼承C洽瞬,C繼承D
A直接繼承了B,間接繼承了C,D业汰;此時A創(chuàng)建的對象伙窃,可以同時使用B,C,D中所有公開的屬性和方法
多繼承
python中,一個類型样漆,可以同時繼承多個類型为障,同時擁有所有繼承類型的所有公開的屬性和方法
備注:在進(jìn)行代碼設(shè)計(jì)的過程中,可能會出現(xiàn)多繼承放祟,所以盡量不要在父類中定義相同名稱的屬性或者方法
備注2:如果父類中出現(xiàn)了相同名稱的屬性和方法鳍怨,在使用的時候子類調(diào)用時會優(yōu)先繼承優(yōu)先調(diào)用。
方法重寫:
子類在自己類中重新定義父類中已經(jīng)存在的方法跪妥,在執(zhí)行該方法時鞋喇,如果子類中沒有重寫就直接調(diào)用父類的方法,如果子類重寫了該方法眉撵,就直接調(diào)用子類重寫的方法侦香!
擴(kuò)展:子類中,訪問父類的屬性和方法:
classUser(Person):
? ? ? ? ? ? ?def__init__(self, name, age):
? ? ? ? ? ? ? ? ? ? ? ? #直接通過父類的類名稱調(diào)用父類的屬性和方法
? ? ? ? ? ? ? ? ? ? ? ? ?Person.__init__(name, age)
? ? ? ? ? ? ? ? ? ? ? ? ?#通過super()來調(diào)用父類的屬性和方法
? ? ? ? ? ? ? ? ? ? ? ? ? super().__init__(name, age)
面向?qū)ο蟮奶卣?--多態(tài)的意義和操作過程
多態(tài)就是多種狀態(tài)纽疟,美其名曰變態(tài)罐韩!程序在運(yùn)行的過程中,根據(jù)傳遞的參數(shù)的不同仰挣,執(zhí)行不同的函數(shù)或者操作不同的代碼伴逸,這種在運(yùn)行過程中才確定調(diào)用的方式成為運(yùn)行時多態(tài)
人民醫(yī)院.治療(病人)
當(dāng)治療方法在執(zhí)行的過程中,根據(jù)傳遞的數(shù)據(jù)的不同膘壶,在執(zhí)行時調(diào)用
病人甲(人) 不同的處理代碼或者處理函數(shù)错蝴,來完成治療效果,動態(tài)處理(多態(tài))
病人乙(男人)
病人丙(女人) 人的類型 VS 動物類型颓芭,不是多態(tài)~而是通過if條件判斷執(zhí)行代碼
病人丁(動物) 人/男人/女人顷锰,執(zhí)行的代碼一致【運(yùn)行過程中,才確定調(diào)用誰的方法】
# 定義一個人的類型
class Person:
# name姓名 age年齡 health健康值【0~50極度虛弱,51~70亞健康,71~85健康亡问,86~100強(qiáng)壯】
def __init__(self, name, age, health):
self.name = name
self.age = age
self.health = health
# 康復(fù)的方法
def recure(self):
print("[%s]康復(fù)了官紫,當(dāng)前健康值%s" % (self.name, self.health))
class Man(Person):
def __init__(self, name, age, health):
Person.__init__(self,name, age, health)
def recure(self):
print("%s哇咔咔,康復(fù)了" % self.name)
class Women(Person):
def __init__(self, name, age, health):
Person.__init__(self,name, age, health)
def recure(self):
print("[%s]死鬼州藕,終于康復(fù)了..." % self.name)
class Animal:
# name姓名 age年齡 health健康值【0~50極度虛弱,51~70亞健康,71~85健康束世,86~100強(qiáng)壯】
def __init__(self, name, age, health):
self.name = name
self.age = age
self.health = health
# 康復(fù)的方法
def recure(self):
print("[%s]嘿嘿嘿,終于康復(fù)了床玻,當(dāng)前健康值%s" % (self.name, self.health))
# 定義人民醫(yī)院
class Hospital:
def __init__(self):
self.name = "人民醫(yī)院"
def care(self, person):
# 類型判斷毁涉,判斷變量person是否Person類型
if isinstance(person, Person):
if person.health > 0 and person.health <= 50:
print("手術(shù)......")
person.health += 30
person.recure()
elif person.health > 50 and person.health <= 70:
print("輸液......")
person.health += 15
person.recure()
else:
print("健康")
else:
print("不好意思,請出門左轉(zhuǎn)锈死,哪里是獸醫(yī)院")
# 醫(yī)院對象
hospital = Hospital()
# 生病的人
old_wang = Person("王先生", 58, 30)
mrs_li = Women("李夫人", 28, 56)
mr_li = Man("李先生", 30, 60)
# 調(diào)用了治療的方法
hospital.care(old_wang)
hospital.care(mrs_li)
hospital.care(mr_li)
a = Animal("tom", 22, 10)
hospital.care(a)