一、面向對象編程
回顧:面向過程編程
是一種之前程序員們設計出來的比較好的編程方法,也是一種編程思想。
核心是過程二字,顧名思義,就是先干什么,再干什么,完成一個事情具有的所有步驟。
優點:復雜的流程簡單化,程序化,一步一步拆分,降低開發難度。
缺點:擴展性差, 不容易維護。
主要使用的場景:對擴展性要求不高的,如Linux內核,shell腳本
何為面向對象?
核心是‘對象’二字。
與面向過程機械式的思維方式形成鮮明對比,面向對象更加注重對現實世界而非流程的模擬,是一種“上帝式”的思維方式。
優點:
1.對於指揮者(程序員)來說,不需要再關心具體步驟
2.擴展性,一個單獨的個體的特征或行為發生變化時 不會影響到別人
缺點:
1.程序的復雜度變高,你得需要設計這些對象,注意要避免過度設計得問題
2.程序得執行結果可控性低
二、類和對象
什么是對象:
在現實生活中實實在在存在的,具備自己的特征和行為的事物
反過來說 對象就是 特征和行為(技能)的結合體
什么是類
一堆具備相同特征和行為的事物的抽象概念,不實際存在。
conclusion:
先有類還是先有對象:
生活中:
生活中類怎么來的,是通過對象的特征和行為抽取而來,
所以是先有對象才有了類
編程中:
必須是先有類 才能有對象,因為你必須先告訴程序,你這個對象有什么樣的特征和行為
類的作用:用於描述該類的對象具備什么樣的特征和行為
補充說明:
站的角度不同,定義出的類是截然不同的;
現實中的類並不完全等於程序中的類,比如現實中的公司類,在程序中有時需要拆分成部門類,業務類等;
有時為了編程需求,程序中也可能會定義現實中不存在的類,比如策略類,現實中並不存在,但是在程序中卻是一個很常見的類
三、Python中類和對象的操作
class Student: # 如果每個對象的這個屬性都相同 才應該定義到類中 比如所有人的學校都相同 school = "北京大學"
# 創建對象 # 語法: 在類名后加括號 與調用函數寫法相同 # stu = Student() # # 訪問對象的屬性 # print(stu.school) # print(Student.school)
# 修改屬性的值 # stu.school = "清華大學" # print(stu.school) # # # 增加屬性 # stu.room_num = "1008" # print(stu.room_num) # # # 刪除屬性 # del stu.room_num # print(stu.room_num)
# 對象 與類的名稱空間是獨立的 # stu.school = "深圳大學" # 為對象的屬性賦予新的值 # print(Student.school) # 類中的屬性不會變化 # stu.room_num = "1008" # 為對象增加屬性 # # print(Student.room_num) #類中也不會出現新的屬性 # print(stu.__dict__) # print(Student.__dict__)
對象的屬性查找順序:
對象自己的名稱空間 -> 類的名稱空間
四、__init__方法詳解
該方法是在對象產生之后才會執行,只用來為對象進行初始化操作,可以有任意代碼,但一定不能有返回值。
__init__稱之為初始化函數 它會在創建對象的時候自動執行
創建對象時
1.創建一個空對象
2.執行__init__函數 並且自動傳入了這個對象
該函數的作用,就是為對象的屬性賦初始值
def __init__(self,name,color,age,gender): print("狗__init__執行了") print(self) self.name = name self.age = age self.color = color self.gender = gender
# 在創建對象時,傳入參數 dog1 = Dog("大黃","黃色",2,"female") dog2 = Dog("二哈","白色",2,"female") print(dog1.__dict__) print(dog2.__dict__)
注意:
1. 使用場景 需要為每個對象定制不同的屬性值
2.__init__在創建對象后自動執行
3.第一個self參數 指的是這個對象本身 不需要手動傳值
五、綁定方法
class Person: country = "China" def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender def sleep(self): print("sleeping")def eat(self): print("eating")
# p1 = Person("矮根",68,"female") # p2 = Person("成偉",18,"female") # 類調用類中函數 與 對象調用的區別 # p1.sleep() # p2.sleep() # print(Person.sleep) # print(p1.sleep) # 類調用 # Person.sleep(10) # 對象調用 # p1.sleep()
類調用與對象調用的區別
對於類而言 sleep就是一個普通函數
對對象而言 sleep是一個綁定方法
綁定方法是什么?
是對象與類中的某個函數的綁定關系 就像生活中 我們都會吃飯 我吃飯你不會飽
那么吃飯就是我自己的綁定方法
為什么要把函數進行綁定?
因為對象的行為 通常都需要訪問這個對象的數據 或是修改這個對象的數據
如果沒有對象 直接調用函數是沒有意義的 在函數中訪問不到對象的數據
所以將對象和函數進行綁定
特殊之處
在使用綁定方法時 不需要關心self參數 會自動將這個對象本身傳進來
對象調用綁定方法時 最后執行的還是類中的那個函數
練習題:
模擬一個王者榮耀對砍游戲,兩個英雄可以對砍 如果血量小於等於0 就GG,考慮所需的對象和英雄的對象。
class Hero: def __init__(self,hero_type,name,blood,q,w,e): self.hero_type = hero_type self.blood = blood self.name = name self.q = q self.w = w self.e = e def Q(self,enemy):# 跳起來給你一刀 print('%s 對 %s 釋放了Q技能 造成%s點傷害,對方剩余血量%s' %(self.name,enemy.name,self.q,enemy.blood-self.q)) enemy.blood -=self.q if enemy.blood <= 0 : print('Hero %s is GG'%enemy.name) def W(self,enemy):# 給你一腳 print('%s 對 %s 釋放了W技能 造成%s點傷害,對方剩余血量%s' %(self.name,enemy.name,self.w,enemy.blood-self.w)) enemy.blood -=self.w if enemy.blood <= 0 : print('Hero %s is GG'%enemy.name) def E(self,enemy):# 大寶劍 print('%s 對 %s 釋放了Q技能 造成%s點傷害,對方剩余血量%s' %(self.name,enemy.name,self.e,enemy.blood-self.e)) enemy.blood -= self.e if enemy.blood <= 0 : print('Hero %s is GG'%enemy.name) # 定義英雄的對象 yashe = Hero('戰士','亞瑟',200,50,30,100) #q,w,e 50,30,100 daji = Hero('法師','妲己',180,10,30,180) #q,w,e 10,30,180 yashe.E(daji) daji.W(yashe) yashe.W(daji) daji.Q(yashe) yashe.Q(daji)
輸出:
亞瑟 對 妲己 釋放了Q技能 造成100點傷害,對方剩余血量80 妲己 對 亞瑟 釋放了W技能 造成30點傷害,對方剩余血量170 亞瑟 對 妲己 釋放了W技能 造成30點傷害,對方剩余血量50 妲己 對 亞瑟 釋放了Q技能 造成10點傷害,對方剩余血量160 亞瑟 對 妲己 釋放了Q技能 造成50點傷害,對方剩余血量0 Hero 妲己 is GG