封裝設計思想
封裝設計思想 - 劃分多個類,再跨類呼叫
需求:老張開車去東北
劃分類:找行為的不同
分析過程:
識別物件:
老張、老李、老孫 --> 屬於資料不同,使用物件區分
人類
車類、船類、飛機類、自行車類 --> 屬於行為不同,使用類區分
東北、西北、陝北 --> 屬於資料不同,使用物件區分
不用做類(因為沒有行為需要承擔)
分配職責:
人類 --> 去
車類 --> 行駛
建立互動:
人類 呼叫 車類
做法1:直接建立物件
# 語義:老張每次去東北都使用一輛新車
class Person: def __init__(self, name=""): self.name = name def go_to(self, pos): print(self.name, "去", pos) c = Car() c.run() class Car: def run(self): print("滴滴滴...") lz = Person("老張") lz.go_to("東北")
做法2:在建構函式中建立物件
# 語義:老張開自己的車去東北
class Person: def __init__(self, name=""): self.name = name self.c = Car() def go_to(self, pos): print(self.name, "去", pos) self.c.run() class Car: def run(self): print("滴滴滴...") lz = Person("老張") lz.go_to("東北")
做法3:通過引數傳遞物件
# 語義:老張通過交通工具(引數)去東北
class Person: def __init__(self, name=""): self.name = name def go_to(self, pos, vehicle): print(self.name, "去", pos) vehicle.run() class Car: def run(self): print("滴滴滴...") lz = Person("老張") c = Car() lz.go_to("東北", c)
繼承
財產:錢,孩子不用掙,但是可以花.
皇位:江山,太子不用打,但是可以坐.
程式設計:程式碼,子類不用寫,但是可以用.
# 多個類有共性,且都屬於一個概念,可以建立父類
class Person:
def say(self):
print("說話")
class Teacher(Person):
def teach(self):
self.say()
print("教學")
class Student(Person):
def play(self):
self.say()
print("玩耍")
# 建立父類物件
p01 = Person()
# 只能訪問父類成員
p01.say()
# 建立子類物件
s01 = Student()
# 能訪問父類成員和子類成員
s01.say()
s01.play()
關係判定相關函式
1. isinstance( 物件 , 型別 )
# 人物件 是一種 人型別 print(isinstance(p01, Person)) # True # 學生物件 是一種 人型別 print(isinstance(s01, Person)) # True # 學生物件 是一種 學生型別 print(isinstance(s01, Student)) # True # 人物件 是一種 學生型別 print(isinstance(p01, Student)) # False
2. issubclass( 型別 , 型別 )
# 人型別 是一種 人型別 print(issubclass(Person, Person)) # True # 學生型別 是一種 人型別 print(issubclass(Student, Person)) # True # 學生型別 是一種 學生型別 print(issubclass(Student, Student)) # True # 人型別 是一種 學生型別 print(issubclass(Person, Student)) # False
3. type(物件) == 型別
# 人物件 是 人型別 print(type(p01) == Person) # True # 學生物件 是 人型別 print(type(s01) == Person) # False # 學生物件 是 學生型別 print(type(s01) == Student) # True # 人物件 是 學生型別 print(type(p01) == Student) # False
繼承資料
1. 子類沒有建構函式,繼承父類建構函式.
2. 子類有建構函式,建立子類物件時,使用子類。
(覆蓋了,父類建構函式,好像它不存在)
class 子類(父類):
def __init__(self,父類建構函式引數,子類建構函式引數):
super().__init__(父類建構函式引數)
self.資料 = 子類建構函式引數
class Person: def __init__(self, name="", age=0): self.name = name self.age = age class Student(Person): # 子類建構函式:父類建構函式引數,子類建構函式引數 def __init__(self, name="", age=0, score=0): # 通過super函式呼叫與子類同名的父類方法. super().__init__(name, age) self.score = score # 過程:呼叫子類建構函式,再呼叫父類建構函式 wk = Student("悟空", 16, 100) print(wk.name) print(wk.age) print(wk.score)
練習:
1. 小明請保潔打掃衛生
理念:找行為不同
寫法1:小明每次通知一個新保潔員
class Client: def __init__(self, name=""): self.name = name def notify(self): print(self.name,"通知") cleaner = Cleaner() cleaner.cleaning() class Cleaner: def cleaning(self): print("保潔員打掃衛生") xm = Client("小明") xm.notify()
寫法2:小明請自己的保潔
class Client: def __init__(self, name=""): self.name = name self.cleaner = Cleaner() def notify(self): print(self.name,"通知") self.cleaner.cleaning() class Cleaner: def cleaning(self): print("保潔員打掃衛生") xm = Client("小明") xm.notify()
寫法3:小明通過保潔服務(保潔員...)打掃衛生
class Client: def __init__(self, name=""): self.name = name def notify(self, service): print(self.name, "通知") service.cleaning() class Cleaner: """ 保潔員 """ def cleaning(self): print("保潔員打掃衛生") xm = Client("小明") cleaner = Cleaner() xm.notify(cleaner)
2.小明在銀行取錢(銀行錢少了,小明錢多了)
class Person: def __init__(self, name="", money=0): self.name = name self.money = money def go_to(self, bank, value): print("小明去取錢") # 呼叫銀行取錢功能,傳遞錢與自身(人) bank.draw_money(value, self) class Bank: def __init__(self, money=0): self.money = money def draw_money(self, value, client): # 銀行錢少 self.money -= value # 客戶錢多 client.money += value print("銀行錢:", self.money, "客戶錢:", client.money) xm = Person("小明", 0) icbc = Bank(100000) # 小明xm去銀行icbc,取100元錢 xm.go_to(icbc, 100) xm.go_to(icbc, 1000) xm.go_to(icbc, 10000)
3.玩家攻擊敵人,敵人受傷(頭頂爆字).
class Player: def attack(self,target): print("攻擊") target.damage() class Enemy: def damage(self): print("頭頂爆字") p01 = Player() e01 = Enemy() p01.attack(e01)
4. 玩家攻擊敵人,敵人受傷(根據玩家攻擊力,減少敵人的血量).
class Player: def __init__(self, atk): self.atk = atk def attack(self, target): print("攻擊") target.damage(self.atk) class Enemy: def __init__(self, hp): self.hp = hp def damage(self, value): self.hp -= value print("敵人受傷,血量是:", self.hp) p01 = Player(10) e01 = Enemy(100) p01.attack(e01) p01.attack(e01)
5. 建立子類:狗(跑),鳥類(飛)
建立父類:動物(吃)
體會子類複用父類方法
體會 isinstance 、issubclass 與 type 的作用.
class Animal: def eat(self): print("吃") class Dog(Animal): def run(self): print("跑") class Bird(Animal): def fly(self): print("飛") a01 = Animal() d01 = Dog() b01 = Bird() d01.run() d01.eat() # 型別 與 型別 的關係 print(issubclass(Animal, Dog)) # 物件 與 型別 的關係 print(isinstance(b01, Animal)) # 狗物件 與 動物型別 相同 print(type(d01) == Animal)
6. 建立父類:車(品牌,速度)
建立子類:電動車(電池容量,充電功率)
建立子類物件並畫出記憶體圖。
class Car: def __init__(self, bread="", speed=0): self.bread = bread self.speed = speed class ElectricCars(Car): def __init__(self, bread, speed, battery_capacity, charging_power=100): super().__init__(bread, speed) self.battery_capacity = battery_capacity self.charging_power = charging_power tsl = ElectricCars("特斯拉", 300, 30000, 1000) print(tsl.bread) print(tsl.speed) print(tsl.battery_capacity) print(tsl.charging_power)