1.1類和對(duì)象
1.1.1萬(wàn)物皆對(duì)象
分類是人們認(rèn)識(shí)世界的一個(gè)很自然的過(guò)程音半,在日常生活中會(huì)不自覺(jué)地將對(duì)象進(jìn)行進(jìn)行分類
對(duì)象歸類
- 類是抽象的概念茅主,僅僅是模板 比如說(shuō):“人”
- 對(duì)象是一個(gè)你能夠看得到桩撮、摸得著的具體實(shí)體: 趙本山愤惰,劉德華徽惋,趙麗穎
舉例
user1 = 'zhangsan'
print(type(user1))
user2 = 'lisi'
print(type(user2))
輸出
<class 'str'>
<class 'str'>
以上str是類(python中的字符串類型),user1和user2是對(duì)象(以前我們叫變量)
研究對(duì)象
顧客類型
屬性:
姓名—張浩
年齡—20
體重—60kg
行為:
購(gòu)買商品
收銀員類型
屬性:
員工號(hào)—10001
姓名—王淑華
部門(mén)—財(cái)務(wù)部
行為:
收款
打印賬單
1.1.2 對(duì)象的特征——屬性
屬性——對(duì)象具有的各種特征仓洼。 每個(gè)對(duì)象的每個(gè)屬性都擁有特定值介陶。 例如:顧客張浩和李明的年齡、姓名不一樣色建。
1.1.4 對(duì)象的特征——方法(操作哺呜,行為)
方法——對(duì)象執(zhí)行的操作(通常會(huì)改變屬性的值)。 顧客對(duì)象的方法---購(gòu)買商品箕戳。 收銀員對(duì)象的方法----收款某残。
對(duì)象:用來(lái)描述客觀事物的一個(gè)實(shí)體,由一組屬性和方法構(gòu)成
例子
類型:狗
對(duì)象名:doudou
屬性:
顏色:白色
方法:
叫陵吸,跑玻墅,吃
對(duì)象同時(shí)具有屬性和方法兩項(xiàng)特性。 對(duì)象的屬性和方法通常被封裝在一起壮虫,共同體現(xiàn)事物的特性澳厢, 二者相輔相承环础,不能分割。
1.1.4 從對(duì)象抽象出“類”
抽取出下列對(duì)象的共同特征(屬性和方法)
類是模子剩拢,定義對(duì)象將會(huì)擁有的特征(屬性)和行為(方法)线得。
再次強(qiáng)調(diào)
- 類是抽象的概念,僅僅是模板徐伐。 比如說(shuō):“人”贯钩, 類定義了人這種類型屬性(name,age...)和方法(study,work...)办素。
- 對(duì)象是一個(gè)你能夠看得到角雷、摸得著的具體實(shí)體: 趙本山,劉德華摸屠,趙麗穎谓罗,這些具體的人都具有人類型中定義的屬性和方法粱哼,不同的是他們各自的屬性不同季二。
根據(jù)類來(lái)創(chuàng)建對(duì)象被稱為實(shí)例化。
1.2 類的定義
1.2.1 定義只包含方法的類
在 Python 中要定義一個(gè)只包含方法的類揭措,語(yǔ)法格式如下:
class 類名:
def 方法1(self, 參數(shù)列表):
pass
def 方法2(self, 參數(shù)列表):
pass
方法 的定義格式和之前學(xué)習(xí)過(guò)的函數(shù) 幾乎一樣胯舷。 區(qū)別在于第一個(gè)參數(shù)必須是 self。
1.2.2 創(chuàng)建對(duì)象
當(dāng)一個(gè)類定義完成之后绊含,要使用這個(gè)類來(lái)創(chuàng)建對(duì)象桑嘶,語(yǔ)法格式如下:
對(duì)象變量 = 類名()
第一個(gè)面向?qū)ο蟪绦?/p>
需求:
- 小貓 愛(ài) 吃 魚(yú),小貓 要 喝 水躬充。
分析:
- 定義一個(gè)貓類
Cat
逃顶。 - 定義兩個(gè)方法
eat
和drink
。
class Cat:
"""這是一個(gè)貓類"""
def eat(self):
print("小貓愛(ài)吃魚(yú)")
def drink(self):
print("小貓?jiān)诤人?)
tom = Cat()
tom.drink()
tom.eat()
使用 Cat 類再創(chuàng)建一個(gè)對(duì)象
lazy_cat = Cat()
lazy_cat.eat()
lazy_cat.drink()
1.3 self 參數(shù)
我們?cè)谡{(diào)用對(duì)象的方法是不需要傳遞self參數(shù)充甚,這個(gè)self參數(shù)是系統(tǒng)自動(dòng)傳遞到方法里的以政。
1.3.1 給對(duì)象增加屬性
在 Python 中,要 給對(duì)象設(shè)置屬性伴找,非常的容易盈蛮,但是不推薦使用。 因?yàn)椋簩?duì)象屬性的封裝應(yīng)該封裝在類的內(nèi)部技矮。 要 給對(duì)象設(shè)置屬性抖誉,只需要在 類的外部的代碼 中直接通過(guò).設(shè)置一個(gè)屬性即可
tom.name = "Tom"
lazy_cat.name = "大懶貓"
1.3.2 理解self到底是什么
class Cat:
"""這是一個(gè)貓類"""
def eat(self):
print(f"小貓愛(ài)吃魚(yú),我是{self.name},self的地址是{id(self)}")
def drink(self):
print("小貓?jiān)诤人?)
tom = Cat()
print(f'tom對(duì)象的id是{id(tom)}')
tom.name = "Tom"
tom.eat()
print('-'*60)
lazy_cat = Cat()
print(f'lazy_cat對(duì)象的id是{id(lazy_cat)}')
lazy_cat.name = "大懶貓"
lazy_cat.eat()
輸出
tom對(duì)象的id是36120000
小貓愛(ài)吃魚(yú),我是Tom,self的地址是36120000
------------------------------------------------------------
lazy_cat對(duì)象的id是36120056
小貓愛(ài)吃魚(yú),我是大懶貓,self的地址是36120056
由輸出可見(jiàn),當(dāng)我們使用的時(shí)候衰倦,python會(huì)自動(dòng)將x對(duì)象做為實(shí)參傳給x方法的self參數(shù)袒炉。 也可以這樣記憶,誰(shuí)點(diǎn)(.)的方法樊零,self就是誰(shuí)
梳杏。
x對(duì)象.x方法()
類中的每個(gè)實(shí)例方法的第一個(gè)參數(shù)都是self
1.4 初始化方法init()
初始化方法
- 當(dāng)使用
類名()
創(chuàng)建對(duì)象時(shí),會(huì)自動(dòng) 執(zhí)行以下操作:
1.為對(duì)象在內(nèi)存中 分配空間 —— 創(chuàng)建對(duì)象(調(diào)用__new__
)
2.為對(duì)象的屬性 設(shè)置初始值 —— 初始化方法(調(diào)用__init__
并且將第一步創(chuàng)建的對(duì)象,通過(guò)self參數(shù)傳給__init__
) - 這個(gè) 初始化方法 就是
__init__
方法十性,__init__
是對(duì)象的內(nèi)置方法(有的書(shū)也叫魔法方法叛溢,特殊方法)
__init__
方法是 專門(mén) 用來(lái)定義一個(gè)類 具有哪些屬性并且給出這些屬性的初始值的方法!
在 Cat
中增加__init__
方法劲适,驗(yàn)證該方法在創(chuàng)建對(duì)象時(shí)會(huì)被自動(dòng)調(diào)用
class Cat:
"""這是一個(gè)貓類"""
def __init__(self):
print("初始化方法")
- 在初始化方法內(nèi)部定義屬性
在__init__
方法內(nèi)部使用 self.屬性名 = 屬性的初始值
就可以 定義屬性
定義屬性之后楷掉,再使用 Cat
類創(chuàng)建的對(duì)象,都會(huì)擁有該屬性
class Cat:
def __init__(self):
print("這是一個(gè)初始化方法")
# 定義用 Cat 類創(chuàng)建的貓對(duì)象都有一個(gè) name 的屬性
self.name = "Tom"
def eat(self):
print("%s 愛(ài)吃魚(yú)" % self.name)
# 使用類名()創(chuàng)建對(duì)象的時(shí)候霞势,會(huì)自動(dòng)調(diào)用初始化方法 __init__
tom = Cat()
tom.eat()
改造初始化方法 —— 初始化的同時(shí)設(shè)置初始值
- 在開(kāi)發(fā)中烹植,如果希望在 創(chuàng)建對(duì)象的同時(shí),就設(shè)置對(duì)象的屬性愕贡,可以對(duì)
__init__
方法進(jìn)行 改造
- 把希望設(shè)置的屬性值草雕,定義成
__init__
方法的參數(shù) - 在方法內(nèi)部使用
self.屬性 = 形參
接收外部傳遞的參數(shù) - 在創(chuàng)建對(duì)象時(shí),使用
類名(屬性1, 屬性2...)
調(diào)用
class Cat:
def __init__(self, name):
print("初始化方法 %s" % name)
self.name = name
tom = Cat("Tom")
lazy_cat = Cat("大懶貓")
1.5_str_
方法
在 Python 中固以,使用 print 輸出 對(duì)象變量墩虹,默認(rèn)情況下,會(huì)輸出這個(gè)變量的類型憨琳,以及 在內(nèi)存中的地址(十六進(jìn)制表示)
class Cat:
def __init__(self, new_name):
self.name = new_name
print("%s 來(lái)了" % self.name)
tom = Cat("Tom")
print(tom)
輸出
Tom 來(lái)了
<__main__.Cat object at 0x0000000002852278>
如果在開(kāi)發(fā)中诫钓,希望使用 print
輸出 對(duì)象變量 時(shí),能夠打印 自定義的內(nèi)容篙螟,就可以利用 __str__
這個(gè)內(nèi)置方法了
注意:
__str__
方法必須返回一個(gè)字符串
class Cat:
def __init__(self, new_name):
self.name = new_name
print("%s 來(lái)了" % self.name)
def __str__(self):
return "我是小貓:%s" % self.name
tom = Cat("Tom")
print(tom)
Tom 來(lái)了
我是小貓:Tom
1.6 面向?qū)ο髒s面向過(guò)程
class Car:
def __init__(self,type,price):
self.type = type
self.price = price
self.distance = 0 #新車
def printCarInfo(self):
print ("the car's Info in class:type %s,price:%d"%(self.type,self.price))
def driveDistance(self,distance):
self.distance += distance
self.price -= distance*10
print(f'面向?qū)ο?)
carOne = Car('passat',250000)
carOne.printCarInfo()
carOne.driveDistance(100)
carOne.driveDistance(200)
print(f'passat已經(jīng)行駛了{(lán)carOne.distance}公里')
print(f'passat的價(jià)格是{carOne.price}')
輸出
面向?qū)ο?the car's Info in class:type passat,price:250000
passat已經(jīng)行駛了300公里
passat的價(jià)格是247000
小結(jié) 可以拿公司運(yùn)營(yíng)作為比喻來(lái)說(shuō)明面向?qū)ο箝_(kāi)發(fā)方式的優(yōu)點(diǎn)
外部調(diào)用代碼好比老板 面向過(guò)程中函數(shù)好比員工菌湃,讓員工完成一個(gè)任務(wù),需要老板不斷的干涉遍略,大大影響了老板的工作效率惧所。 面向?qū)ο笾袑?duì)象好比員工,讓員工完成一個(gè)任務(wù)绪杏,老板只要下命令即可下愈,員工可以獨(dú)擋一面,大大節(jié)省了老板的時(shí)間
還有一種說(shuō)法
世界上本沒(méi)有類寞忿,代碼寫(xiě)多了驰唬,也就有了類
面向?qū)ο箝_(kāi)發(fā)方式是晚于面向過(guò)程方式出現(xiàn)的,幾十年前腔彰,面向?qū)ο筮€沒(méi)有出現(xiàn)以前叫编,很多軟件系統(tǒng)的代碼量就已經(jīng)達(dá)到幾十上百萬(wàn)行,科學(xué)家為了組織這些代碼霹抛,將各種關(guān)系密切的數(shù)據(jù)搓逾,和相關(guān)的方法分門(mén)別類,放到一起管理杯拐,就形成了面向?qū)ο蟮拈_(kāi)發(fā)思想和編程語(yǔ)言語(yǔ)法霞篡。