什么是面向?qū)ο螅?
面向?qū)ο蠹夹g(shù)簡(jiǎn)介
- 類(lèi)(Class): 用來(lái)描述具有相同的屬性和方法的對(duì)象的集合。它定義了該集合中每個(gè)對(duì)象所共有的屬性和方法。對(duì)象是類(lèi)的實(shí)例。
- 方法:類(lèi)中定義的函數(shù)。
- 類(lèi)變量:類(lèi)變量在整個(gè)實(shí)例化的對(duì)象中是公用的。類(lèi)變量定義在類(lèi)中且在函數(shù)體之外。類(lèi)變量通常不作為實(shí)例變量使用。
- 數(shù)據(jù)成員:類(lèi)變量或者實(shí)例變量用于處理類(lèi)及其實(shí)例對(duì)象的相關(guān)的數(shù)據(jù)。
- 方法重寫(xiě):如果從父類(lèi)繼承的方法不能滿足子類(lèi)的需求,可以對(duì)其進(jìn)行改寫(xiě),這個(gè)過(guò)程叫方法的覆蓋(override),也稱(chēng)為方法的重寫(xiě)。
- 局部變量:定義在方法中的變量,只作用于當(dāng)前實(shí)例的類(lèi)。
- 實(shí)例變量:在類(lèi)的聲明中,屬性是用變量來(lái)表示的。這種變量就稱(chēng)為實(shí)例變量,是在類(lèi)聲明的內(nèi)部但是在類(lèi)的其他成員方法之外聲明的。
-
繼承:即一個(gè)派生類(lèi)(derived class)繼承基類(lèi)(base
class)的字段和方法。繼承也允許把一個(gè)派生類(lèi)的對(duì)象作為一個(gè)基類(lèi)對(duì)象對(duì)待。例如,有這樣一個(gè)設(shè)計(jì):一個(gè)Dog類(lèi)型的對(duì)象派生自Animal類(lèi),這是模擬"是一個(gè)(is-a)"關(guān)系(例圖,Dog是一個(gè)Animal)。 - 實(shí)例化:創(chuàng)建一個(gè)類(lèi)的實(shí)例,類(lèi)的具體對(duì)象。
- 對(duì)象:通過(guò)類(lèi)定義的數(shù)據(jù)結(jié)構(gòu)實(shí)例。對(duì)象包括兩個(gè)數(shù)據(jù)成員(類(lèi)變量和實(shí)例變量)和方法。
面向?qū)ο笠欢ㄒ蓄?lèi),以下介紹均基于類(lèi)
類(lèi)(Class): 用來(lái)描述具有相同的屬性和方法的對(duì)象的集合。它定義了該集合中每個(gè)對(duì)象所共有的屬性和方法。對(duì)象是類(lèi)的實(shí)例。
屬性,就是數(shù)據(jù),包括類(lèi)變量和實(shí)例變量
方法,就是操作數(shù)據(jù)的行為,包括實(shí)例方法、類(lèi)方法和靜態(tài)方法
為什么要使用類(lèi)呢?
每個(gè)類(lèi)都是一個(gè)模板,統(tǒng)一存儲(chǔ)數(shù)據(jù)和操作數(shù)據(jù)的規(guī)則
每個(gè)類(lèi)都是一個(gè)類(lèi)別,基于這個(gè)類(lèi)別管理數(shù)據(jù),方便查找和操作
基于類(lèi)可以實(shí)現(xiàn)繼承和多態(tài),方便程序的擴(kuò)展
類(lèi)作為一個(gè)整體,把一組組相關(guān)數(shù)據(jù)放到類(lèi)的實(shí)例里面,進(jìn)行存儲(chǔ),計(jì)算等,實(shí)現(xiàn)安全性、獨(dú)立性,規(guī)則的操作統(tǒng)一,保證數(shù)據(jù)的一致性和完整性。
什么是封裝?
將對(duì)象的數(shù)據(jù)與操作數(shù)據(jù)的方法相結(jié)合,通過(guò)方法將對(duì)象的數(shù)據(jù)與實(shí)現(xiàn)細(xì)節(jié)保護(hù)起來(lái),就稱(chēng)為封裝。外界只能通過(guò)對(duì)象的方法訪問(wèn)對(duì)象,因此封裝同時(shí)也實(shí)現(xiàn)了對(duì)象的數(shù)據(jù)隱藏。通過(guò)封裝和數(shù)據(jù)隱藏機(jī)制,將一個(gè)對(duì)象相關(guān)的變量和方法封裝為一個(gè)獨(dú)立的軟件體,單獨(dú)進(jìn)行實(shí)現(xiàn)和維護(hù),并使對(duì)象能夠在系統(tǒng)內(nèi)方便地進(jìn)行傳遞,另外也保證了對(duì)象數(shù)據(jù)的一致性并使程序易于維護(hù),封裝可以讓調(diào)用者不用關(guān)心對(duì)象是如何構(gòu)建的而直接進(jìn)行使用。
函數(shù)和類(lèi)中的方法都可以實(shí)現(xiàn)封裝,那么他們有什么區(qū)別呢?
類(lèi):
專(zhuān)有數(shù)據(jù)(可以存儲(chǔ),和對(duì)外使用)
方法(用于操作專(zhuān)有數(shù)據(jù)的),實(shí)現(xiàn)操作數(shù)據(jù)的規(guī)則。類(lèi)實(shí)例不但有操作某些數(shù)據(jù)的過(guò)程和算法,且保存相關(guān)的數(shù)據(jù)
函數(shù):
無(wú)專(zhuān)有數(shù)據(jù),誰(shuí)給他傳值都可以處理,并返回,函數(shù)只有操作某些數(shù)據(jù)的過(guò)程和算法,但本身不能存儲(chǔ)數(shù)據(jù)。
所以類(lèi)和函數(shù)的區(qū)別在于是否保存數(shù)據(jù)
一個(gè)簡(jiǎn)單的類(lèi)的例子:
class P:
def __init__(self,value): #構(gòu)造方法,初始化用的
self.value = value #value局部變量
#self.value叫做實(shí)例變量
p =P(10)
print(p.value) #打印10
兩個(gè)下劃線開(kāi)頭的方法或者是變量,都是私有的。
私有的變量和方法,只能類(lèi)內(nèi)部的方法去調(diào)用,外部不可以
拿上面的例子說(shuō),如果是self.__value = value,print(p.__value),這樣就會(huì)報(bào)錯(cuò),因?yàn)橥獠坎荒苁褂妙?lèi)里的私有變量
類(lèi):
一組數(shù)據(jù)(可以是0個(gè)、1個(gè)或多個(gè)),以及提供操作這組數(shù)據(jù)的相關(guān)方法,數(shù)據(jù)和方法組成了類(lèi)。
類(lèi)定義的所有內(nèi)容,在內(nèi)存中僅有一份(類(lèi)變量和類(lèi)方法)
類(lèi)實(shí)例(多個(gè)),每個(gè)類(lèi)實(shí)例在內(nèi)存中都有自己的空間。
類(lèi)名全大寫(xiě)
class PERSON(object):
def __init__(self,name,sex,height,weight,bachelor):
self.name = name
self.sex = sex
self.height = height
self.weight = weight
self.bachelor = True
def print_name(self):
print(self.name)
alex = PERSON("Alex","M",180,200,True)
mike = PERSON("Mike","M",101,250,False)
print(alex.weight)
print(mike.weight)
alex.weight += 1
print(alex.weight)
alex.print_name()
類(lèi)的方法里面為啥要有個(gè)self呢?
alex.print_name()---->在內(nèi)存中找到類(lèi)定義所在的內(nèi)存位置,找到類(lèi)里面定義的方法print_name(),self—>alex所在的內(nèi)存地址,使用alex實(shí)例中的name值進(jìn)行打印。
類(lèi):存儲(chǔ)、管理、操作一組特定的數(shù)據(jù)的。通過(guò)私有變量和相應(yīng)的操作方法,來(lái)保證數(shù)據(jù)的一致性和完整性。
保證數(shù)據(jù)的安全性有2種方法:
方法1:
設(shè)定私有變量__xxx,通過(guò)get_xxx()取數(shù)據(jù),通過(guò)set_xxx賦值
取數(shù)據(jù)和設(shè)置數(shù)據(jù)的規(guī)則都在方法里。
__xxx是安全的,只能通過(guò)實(shí)例方法去訪問(wèn)。
方法2:
使用公有變量,通過(guò)@property 來(lái)讀取數(shù)據(jù),
通過(guò)@xxxx.setter來(lái)設(shè)置數(shù)據(jù)。
數(shù)據(jù)也是安全的,因?yàn)橛?個(gè)方法來(lái)設(shè)定取數(shù)據(jù)和修改數(shù)據(jù)規(guī)則。
class Goods(object):
def __init__(self,pri):
self.pri = pri
@property
def price(self):
return int(self.pri)
@price.setter
def price(self, value):
if self.pri>=100 or self.pri<0:
return None
@price.deleter
def price(self):
print("價(jià)格變量被刪除了!")
del self.pri
#調(diào)用
obj = Goods(50.50)
print(obj.price) # 自動(dòng)執(zhí)行 @property 修飾的 price 方法,并獲取方法的返回值,打印50
obj.price = 123 # 自動(dòng)執(zhí)行 @price.setter 修飾的 price 方法,并將 123 賦值給方法的參數(shù)
print(obj.price) #打印50
del obj.price # 自動(dòng)執(zhí)行 @price.deleter 修飾的 price 方法,打印 價(jià)格變量被刪除了!
類(lèi)的特殊成員
1.__doc__表示類(lèi)的描述信息
2.__module__表示當(dāng)前操作的對(duì)象在哪個(gè)模塊
3.__class__表示當(dāng)前操作的對(duì)象的類(lèi)是什么
4.__del__析構(gòu)方法,當(dāng)對(duì)象在內(nèi)存中被釋放時(shí),自動(dòng)觸發(fā)執(zhí)行
注:此方法一般無(wú)須定義,因?yàn)镻ython是一門(mén)高級(jí)語(yǔ)言,程序員在使用時(shí)無(wú)需關(guān)系內(nèi)存的分配和釋放,因?yàn)榇斯ぷ鞫际墙唤oPython解釋器來(lái)執(zhí)行,所以,析構(gòu)函數(shù)的調(diào)用是由解釋器在進(jìn)行垃圾回收時(shí)自動(dòng)觸發(fā)執(zhí)行的。
5.__call__對(duì)象后面加括號(hào),觸發(fā)執(zhí)行
注:構(gòu)造方法的執(zhí)行是由創(chuàng)建對(duì)象觸發(fā)的,即:對(duì)象=類(lèi)名();而對(duì)于__call__方法的執(zhí)行是由對(duì)象后加括號(hào)觸發(fā)的,即:對(duì)象()或類(lèi)()()
6.__dict__類(lèi)或?qū)ο笾械乃谐蓡T
類(lèi)的普通字段屬于對(duì)象;類(lèi)中的靜態(tài)字段和方法等屬于類(lèi)
7.__str__如果一個(gè)類(lèi)中定義了__str__方法,那么在打印對(duì)象時(shí),默認(rèn)輸出該方法的返回值。
8.
getitem
、
setitem
、__delitem__用于索引操作,如字典。以上分別表示獲取、設(shè)置、刪除數(shù)據(jù)
9.
getslice
、
setslice
、
delslice__在python2.7可以使用,在3.x已經(jīng)被去掉了,需要使用__getitem
、
setitem
、__delitem__和__getslice__來(lái)實(shí)現(xiàn)
10.
iter__用于迭代器,之所以列表、字段、元組可以進(jìn)行for循環(huán),是因?yàn)轭?lèi)型內(nèi)部定義了__iter
11.__slot__限制實(shí)例可以使用的屬性名稱(chēng)
12.__metaclass__用途較少
13.__new__在類(lèi)準(zhǔn)備將自身實(shí)例化時(shí)調(diào)用,
new
()方式始終都是類(lèi)的靜態(tài)方法,即使沒(méi)有被加上靜態(tài)方法裝飾器
類(lèi)實(shí)現(xiàn)了如下方法,就是可以迭代的對(duì)象
iter
()
next
()
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
