需求:士兵突進
- 士兵許三多有一把 AK47
- 士兵可以開火
- 槍能夠發射子彈
- 槍裝填子彈,可以增加子彈數量
需求分析
- 很明顯有兩個類:士兵類,槍類
- AK47 是槍名,是槍類的屬性,每把槍都有子彈數,所以子彈數也是一個屬性
- 發生子彈是一個行為,所以是一個方法
- 裝填子彈也是一個行為,也是一個方法
- 許三多是姓名,是士兵類的屬性;士兵擁有槍,所以槍也是一個屬性,對應的是槍類【一個對象的屬性可以是另外一個類創建的對象】
- 開火是士兵類的一個行為,所以是一個方法,開火會發射子彈,所以應該調用槍的發射方法
類圖

本次實戰采用封裝思想,將所有屬性私有化,並且每個屬性都有 setter、getter 方法
代碼實現
- 面向對象編程的第一步:將屬性和方法封裝到一個抽象的類中
- 外接使用類創建對象,然后讓對象調用方法
- 對象方法的細節都被封裝在類的內部
先開發槍類還是士兵類?
槍類,因為士兵類依賴槍類,被依賴的類應該優先開發
槍類
假設每把槍一開始都沒子彈,需要先手動裝彈
class Gun: # 構造方法 def __init__(self, name): # 封裝 - 將實例屬性私有化 self.__name = name self.__bullet_count = 0 # 自定義打印對象方法 def __str__(self): return f"槍名:{self.__name} 子彈數:{self.__bullet_count}" # name - getter @property def name(self): return self.__name # name - setter @name.setter def name(self, name): self.__name = name # count - getter @property def bulletCount(self): return self.__bullet_count # count - setter 相當於裝子彈 @bulletCount.setter def bulletCount(self, count): self.__bullet_count += count # shot 發射 def shoot(self): # 1、判斷是否能發射 if self.__bullet_count <= 0: print(f"{self.__name} 沒有子彈了,請先裝彈") return # 2、發射 print(f"槍名:{self.__name} 發射") # 3、減少子彈 self.__bullet_count -= 1
士兵類
假設每一個新兵一開始都沒有槍
class Solider: # 構造方法 def __init__(self, name): self.__name = name # 默認沒有槍 self.__gun = None # 自定義打印對象方法 def __str__(self): return f"士兵名字:{self.__name} 拿着一把:{self.__gun.name}" # name - getter @property def name(self): return self.__name # name - setter @name.setter def name(self, name): self.__name = name # gun - getter @property def gun(self): return self.__gun @gun.setter def gun(self, gun): self.__gun = gun def fire(self): # 1、先判斷是有槍 if self.__gun is None: print(f"{self.__name} 士兵沒有槍,不能發射!!請先裝備槍!!") return # 2、有槍也要有子彈呀!上膛! self.__gun.bulletCount += 10 # 3、拿槍射擊! self.__gun.shoot()
拿槍射擊,其實是
執行代碼塊
# 聲明一個槍 ak47 = Gun("ak47") print(ak47) # 聲明一個士兵 xusanduo = Solider("許三多") # 給士兵帶上 AK47! xusanduo.gun = ak47 # 開火! xusanduo.fire() print(xusanduo) # 輸出結果 槍名:ak47 子彈數:0 槍名:ak47 發射 士兵名字:許三多 拿着一把:ak47
