面向對象:字典實現人狗大戰、自定義類、調用類中的方法、類的內容查看、修改、添加、使用類來完成人狗大戰 ...
面向對象
字典實現人狗大戰
#定義角色 def Person(name,hp,aggr,sex): person = { 'name':name, 'hp':hp, 'aggr':aggr, 'sex':sex } return person def Dog(name,hp,aggr,kind): dog = { 'name':name, 'hp':hp, 'aggr':aggr, 'kind':kind } return dog
#定義技能 #打 def attack(person,dog): dog['hp'] -= person['aggr'] print('%s損失了%s的血量'%(dog['name'],person['aggr'])) #咬 def bite(dog,person): person['hp'] -= dog['aggr'] print('%s損失了%s的血量'%(person['name'],dog['aggr']))
#print(Person('new',100,2,'不祥')) #print(Dog('二哈',100,3,'taddy')) man = Person('雷諾',100,2,'不祥') #實例化 dogs = Dog('二哈',100,3,'taddy') bite(dogs,man) print(man)
這樣會出現一個問題,就是把角色搞混
我們把技能封裝到任務所屬的函數中,這個就不容易把任務關係搞混了
def Person(name,hp,aggr,sex): person = { 'name':name, 'hp':hp, 'aggr':aggr, 'sex':sex } def attack(dog): dog['hp'] -= person['aggr'] print('%s損失了%s的血量'%(dog['name'],person['aggr'])) person['attack'] = attack return person def Dog(name,hp,aggr,kind): dog = { 'name':name, 'hp':hp, 'aggr':aggr, 'kind':kind } def bite(person): person['hp'] -= dog['aggr'] print('%s損失了%s的血量'%(person['name'],dog['aggr'])) dog['bite'] = bite return dog man = Person('new',100,2,'不祥') dogs = Dog('二哈',100,3,'taddy') man['attack'](dogs) #然後我們就可以這樣來調用 Person 函數中的 attack 函數 dogs['bite'](man)
簡單小結:
Dog 函數和 Person 函數 都是定義了一類事物
直到調用了函數,賦值了之後才真的有了一個實實在在的人或狗
代碼精簡了 方便增加人物 方便修改 人物更加規範 —— 人模子
面向對象編程
所謂模子 就是 類 抽象的 我能知道有什麼屬性 有什麼技能 但不能知道屬性具體的值
人 屋子 就是對象 有具體的值,屬性和技能都是根據類規範的
面向過程 VS 面向對象
面向過程的程式設計的核心是過程(流水線式思維)
優點是:極大的降低了寫程式的複雜度,只需要順著要執行的步驟,堆疊代碼即可
缺點是:一套流水線或者流程就是用來解決一個問題,代碼牽一發而動全身。
應用場景:一旦完成基本很少改變的場景,著名的例子有 Linux 內核,git,以及Apache HTTP Server等
面向對象的程式設計的
優點是:解決了程式的擴展性。對某一個對象單獨修改,會立刻反映到整個體系中,如對游戲中一個人物參數的特征和技能修改都很容易。
缺點:可控性差,無法像面向過程的程式設計流水線式的可以很精準的預測問題的處理流程與結果,面向對象的程式一旦開始就由對象之間的交互解決問題,即便是上帝也無法預測最終結果。於是我們經常看到一個游戲人某一參數的修改極有可能導致陰霸的技能出現,一刀砍死3個人,這個游戲就失去平衡。
應用場景:需求經常變化的軟體,一般需求的變化都集中在用戶層,互聯網應用,企業內部軟體,游戲等都是面向對象的程式設計大顯身手的好地方
自定義類
#定義 class 類名: 屬性 = 'a' #查看 print(類名.屬性) # 類名的作用 就是操作屬性 查看屬性
我們來看一個例子
class Person: # 類名 def __init__(solf,*args): # 初始化方法,self是對象,是一個必須傳的參數 solf.name = args[0] # self 就是一個可以存儲很多屬性的大字典 solf.hp = args[1] # 而往字典里添加屬性的方式發生了一些變化 solf.aggr = args[2] solf.sex = args[3] per = Person('小強',100,3,'不祥') print(per) #返回的是一個記憶體地址 print(per.name) #查看屬性值 print(per.hp) #查看屬性值 print(per.aggr) #查看屬性值
調用類中的方法
#調用類中的方法 class Person: count = 'China' # 創造了一個只要是這個類就一定有的屬性,這個是類擁有的 而不是屬性 # 類屬性 靜態屬性 def __init__(self,*args):# 初始化方法 self.name = args[0] self.hp = args[1] self.aggr = args[2] self.sex = args[3] def run(self,n): #定義了一個方法,一般情況下必須傳 self 參數,且必須寫在第一個 #後面還可以傳其他參數,是自由的 print('%s跑跑跑,跑了%s公裡'%(self.name,n)) ##2.接收參數 per = Person('小強',100,3,'不祥') print(Person.__dict__) #可以看到 Person 方法中有 run 這個函數(#查看所有屬性) print(Person.run) #為一個記憶體地址 Person.run(per,6) #此處為什麼是 per,因為在賦值使用 Person 函數後 self 的值返回給了 per #per.run() #另一種簡便方法 對象名 + 方法名 與 Person.run(per) 等價 per.run(5) ##1.傳值 print(per.count) #獲取靜態屬性
類的內容查看、修改、添加
#接上 #對類的內容查看、修改、添加 print(Person.__dict__) #得到的是類中存儲的所有名字 print(Person.__dict__['count']) #可以通過 __dict__ 使用字典的方式操作 print(per.__dict__) #得到的 per 所有屬性 print(per.__dict__['name']) per.__dict__['name'] = '小吼' #可以查看也可以修改 print(per.__dict__['name']) print(per.name) per.name = '鳥人' #不過一般通過屬性來修改 print(per.name) per.age = 49 #增加 print(per.__dict__)
簡單小結:
對象 = 類名()
過程:
類名() 首先 會創造出一個對象,創建了一個self變數
調用 init 方法,類名括弧里的參數會被這裡接收
執行 init 方法
返回 self
對象能做的事:
查看屬性
調用方法
__dict__ 對於對象的增刪改查操作都可以通過字典的語法進行
類名能做的事:
實例化
調用方法 : 只不過要自己傳遞 self 參數
調用類中的屬性,也就是調用靜態屬性
__dict__ 對於類中的名字只能看 不能操作 比如:修改 count,報錯
接著我要切入主題了
使用類來完成我們最初的游戲:人狗大戰
#大致如下 class Person: def __init__(self,name,hp,aggr,sex): self.name = name self.hp = hp self.aggr = aggr self.sex =sex def attack(self,dog): dog.hp -= self.aggr print('%s 損失了 %s 點 hp'%(dog.name,self.aggr)) class Dog: def __init__(self,name,hp,aggr,kind): self.name = name self.hp = hp self.aggr = aggr self.kind = kind def bite(self,person): person.hp -= self.aggr self.hp -= person.aggr print('%s 損失了 %s 點 hp'%(person.name,self.aggr)) if person.hp < 0: print('%s 失血過多戰敗,%s 剩餘 %s 點 HP'%(person.name,self.name,self.hp)) else: print('%s 此回合戰勝%s,剩餘 %s 點 hp,%s 剩餘%s 點 HP'%(person.name,self.name,person.hp,self.name,self.hp)) per = Person('雷諾',100,23,'男') dog = Dog('異蟲',200,12,'未知',) while 1: dog.bite(per) if per.hp < 0 or dog.hp < 0: break
流程
定義類
init 方法
self 是什麼 self擁有屬性都屬於對象
類中可以定義靜態屬性
類中可以定義方法,方法都有一個必須傳的參數 self
實例化
實例、對象
對象查看屬性
對象調用方法
小結:
定義類
class
函數 : 方法 動態屬性 # 類中可以定義方法,方法都有一個必須傳的參數 self
變數 : 類屬性 靜態屬性 # 類中可以定義靜態屬性
__init__ 方法 初始化方法
python 幫我們創建了一個對象 self
每當我們調用類的時候就會自動觸發這個方法。預設傳 self
在 init 方法裡面可以對 self 進行賦值
self 是什麼 self 擁有屬性都屬於對象
在類的內部,self 就是一個對象
alex = Person()
alex.walk == Person.walk(alex)
實例化
對象 = 類(參數是 init 方法的)
實例、對象 完全沒有區別
對象查看屬性
對象.屬性名
對象調用方法
對象.方法名(參數) #類名.方法名(對象名,參數)