封装设计思想 - 划分多个类,再跨类调用
需求:老张开车去东北
划分类:找行为的不同
分析过程:
识别对象:
老张、老李、老孙 --> 属于数据不同,使用对象区分
人类
车类、船类、飞机类、自行车类 --> 属于行为不同,使用类区分
东北、西北、陕北 --> 属于数据不同,使用对象区分
不用做类(因为没有行为需要承担)
分配职责:
人类 --> 去
车类 --> 行驶
建立交互:
人类 调用 车类
做法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)