一. 類空間,對象空間
1. 類空間,對象空間
創建一個類就會創建一個類的名稱空間,用來存儲類中定義的所有名字,這些名字稱為類的屬性
而類有兩種屬性:靜態屬性和動態屬性
- 靜態屬性就是直接在類中定義的變量
- 動態屬性就是定義在類中的方法
其中類的數據屬性是共享給所有對象的,用類名是找不到對象屬性的
創建一個對象/實例就會創建一個對象/實例的名稱空間,存放對象/實例的名字,稱為對象/實例的屬性. 在obj.name會先從obj自己的名稱空間里找name,找不到則去類中找,類也找不到就找父類...最后都找不到就拋出異常.
查詢順序:
對象.屬性 : 先從對象空間找,如果找不到,再從類空間找,再找不到,再從父類找...
類名.屬性 : 先從本類空間找,如果找不到,再從父類找....
class Person: animal = '高級動物' soul = '有靈魂' language = '語言' def __init__(self, country, name, sex, age, hight): self.country = country self.name = name self.sex = sex self.age = age self.hight = hight def eat(self): print('%s吃飯' % self.name) def sleep(self): print('睡覺') def work(self): print('工作') p1 = Person('菲律賓', 'alex', '未知', 42, 175) p1.animal = '禽獸' # 通過對象不能改變,只能引用類中的靜態變量, 所以修改的不是類中的animal,而是對象p1自己添加了animal屬性. print(p1.animal) # 禽獸 先查找對象里有沒有animal屬性,如果沒有,再去類中查找. print(Person.animal) # 高級動物 # print(Person.name) #報錯,無法用類名查找對象的屬性
計算對象實例化的次數
class Lei: num = 0 def __init__(self, name, sex): self.name = name self.sex = sex Lei.num = Lei.num + 1 # 要想使用類中的靜態變量,必須要用'類名.'去使用 def func(self): print(self.name, self.sex) obj1 = Lei('alex', '男') obj2 = Lei('good', '女') obj3 = Lei('better', '男') print(Lei.num) # 3
二. 組合
組合: 給一個類的對象封裝一個屬性,這個屬性是另一個類的對象.
通過例題來看一下什么是組合
模擬英雄聯盟寫一個游戲人物的類 要求: (1)創建一個 Game_role的類. (2) 構造方法中給對象封裝name,ad(攻擊力),hp(血量).三個屬性. (3) 創建一個attack方法,此方法是實例化兩個對象,互相攻擊的功能: 例: 實例化一個對象 蓋倫,ad為10, hp為100 實例化另個一個對象 劍豪 ad為20, hp為80 蓋倫通過attack方法攻擊劍豪,此方法要完成 '誰攻擊誰,誰掉了多少血, 還剩多少血'的提示功能.
class Game_role: def __init__(self, name, ad, hp): self.name = name self.ad = ad self.hp = hp def attack(self, g): g.hp = g.hp - self.ad # 劍豪剩余的血為劍豪的總血減去蓋倫的攻擊 print('%s攻擊%s,%s掉了%s血, 還剩%s血' % (self.name, g.name, g.name, self.ad, g.hp)) g1 = Game_role('蓋倫', 10, 100) # 實例化第一個對象 g2 = Game_role('劍豪', 20, 80) # 實例化第二個對象 g1.attack(g2) # g1調用方法attack,並把g2傳給方法attack里的參數'g' # 蓋倫攻擊劍豪,劍豪掉了10血, 還剩70血 print(g2.hp) # 70
要增加武器(刀棍道等), 需要增加一個類(武器名稱,攻擊力). 結果要求顯示為 : '誰用什么武器攻擊誰,誰掉了多少血, 還剩多少血'
class Game_role: def __init__(self, name, ad, hp): self.name = name self.ad = ad self.hp = hp def attack(self, g): g.hp = g.hp - self.ad # 劍豪剩余的血為劍豪的總血減去蓋倫的攻擊 print('%s攻擊%s,%s掉了%s血, 還剩%s血' % (self.name, g.name, g.name, self.ad, g.hp)) def armament_weapon(self, wea): self.wea = wea # 給角色封裝一個新的屬性(武器) class Weapon: def __init__(self, name, ad): self.name = name self.ad = ad def fight(self, g1, g2): g2.hp = g2.hp - self.ad print('%s 用%s攻擊%s,%s 掉了%s血,還剩%s血' \ % (g1.name, self.name, g2.name, g2.name, self.ad, g2.hp)) g1 = Game_role('蓋倫', 10, 100) g2 = Game_role('劍豪', 20, 80) w1 = Weapon('斧頭', 30) g1.armament_weapon(w1) # 把武器的屬性傳給Game_role類里的armament_weapon方法 print(g1.wea) # 其實就是w1 g1.wea.fight(g1, g2) # g1.wea.fight() = w1.fight() print(g2.hp) #50