封装设计思想
1. 识别对象
2. 分配职责
3. 建立交互
"""
封装设计思想
需求:老张开车去东北
类:承担行为
对象:承担数据
1. 识别对象
老张 车
2. 分配职责
去() 行驶()
3. 建立交互
老张调用车
"""
# lz = Person("老张")
# ls = Person("老孙")
"""
# 写法1:直接创建对象
# 语义: 老张去东北用一辆新车
class Person:
def __init__(self, name=""):
self.name = name
def go_to(self,position):
print(self.name,"去",position)
car = Car()
car.run()
class Car:
# 实例方法
def run(self):
print("汽车在行驶")
lw = Person("老王")
lw.go_to("东北")
lw.go_to("西北")
"""
"""
# 写法2:在构造函数中创建对象
# 语义: 老张开车自己的车去东北
class Person:
def __init__(self, name=""):
self.name = name
self.car = Car()
def go_to(self,position):
print(self.name,"去",position)
# 第一次.: 从栈帧到人对象
# 第二次.: 从人到车对象
self.car.run()
class Car:
# 实例方法
def run(self):
print("汽车在行驶")
lw = Person("老王")
lw.go_to("东北")
lw.go_to("西北")
"""
# 写法3:通过参数传递对象
# 语义:人通过交通工具(参数传递而来)去东北
class Person:
def __init__(self, name=""):
self.name = name
def go_to(self,position,vehicle):
print(self.name,"去",position)
vehicle.run()
class Car:
# 实例方法
def run(self):
print("汽车在行驶")
lw = Person("老王")
c01 = Car()
lw.go_to("东北",c01)
类与类调用语法
写法1:直接创建对象调
写法2:构造函数创建对象调
写法3:构造函数创建对象调
"""
总结
类与类调用语法
"""
# 函数互相调用:通过函数名直接调用
# def func01():
# func02()
#
# def func02():
# print("func02")
#
# func01()
# 写法1:直接创建对象调
# class A:
# def func01(self):
# b = B()
# b.func02()
#
# class B:
# def func02(self):
# print("func02")
#
# g01 = A()
# g01.func01()
# 写法2:构造函数创建对象调
# class A:
# def __init__(self):
# self.b = B()
#
# def func01(self):
# self.b.func02()
#
# class B:
# def func02(self):
# print("func02")
#
# g01 = A()
# g01.func01()
# 写法3:构造函数创建对象调
class A:
def func01(self, c):
c.func02()
class B:
def func02(self):
print("func02")
g01 = A()
g02 = B()
g01.func01(g02)
继承
语法角度讲
继承方法
1. 代码:
class 父类:
def 父类方法(self):
方法体
class 子类(父类):
def 子类方法(self):
方法体
儿子 = 子类()
儿子.子类方法()
儿子.父类方法()
2. 说明:子类直接拥有父类的方法.
"""
继承
财产:钱不用儿子挣,但是儿子能花
皇位:江山不用太子打,但是太子能登基
编程:代码不用子类写,但是子类能使用
"""
# 从思想讲:先有子再有父
# 从编码讲:先有父再有子
# 多个类有代码的共性,且属于共同一个概念。
class Person:
def say(self):
print("说话")
class Student(Person):
def study(self):
self.say()
print("学习")
class Teacher(Person):
def teach(self):
print("教学")
# 创建子类对象,可以调用父类方法和子类方法
s01 = Student()
s01.say()
s01.study()
# 创建父类对象,只能调用父类方法
p01 = Person()
p01.say()
# isinstance(对象,类型) 判断关系
# 学生对象 是一种 学生类型
print(isinstance(s01, Student)) # True
# 学生对象 是一种 人类型
print(isinstance(s01, Person)) # True
# 学生对象 是一种 老师类型
print(isinstance(s01, Teacher)) # False
# 人对象 是一种 学生类型
print(isinstance(p01, Student)) # False
# issubclass(类型,类型) 判断关系
# 学生类型 是一种 学生类型
print(issubclass(Student, Student)) # True
# 学生类型 是一种 人类型
print(issubclass(Student, Person)) # True
# 学生类型 是一种 老师类型
print(issubclass(Student, Teacher)) # False
# 人类型 是一种 学生类型
print(issubclass(Person, Student)) # False
# Type
# type(对象) == 类型 相等/相同/一模一样
# 学生对象的类型 是 学生类型
print(type(s01) == Student) # True
# 学生对象的类型 是 人类型
print(type(s01) == Person) # False
# 学生对象的类型 是 老师类型
print(type(s01) == Teacher) # False
# 人对象的类型 是 学生类型
print(type(p01) == Student) # False
继承数据
1. 代码
class 子类(父类):
def init(self,参数列表):
super().init(参数列表)
self.自身实例变量 = 参数
2. 说明
子类如果没有构造函数,将自动执行父类的,但如果有构造函数将覆盖父类的。此时必须通过super()函数调用父类的构造函数,以确保父类实例变量被正常创建。
继承数据
1. 子类没有构造函数,可以直接使用父类的
2. 子类有构造函数,会覆盖父类构造函数(好像他不存在)
所以子类必须通过super()调用父类构造函数
"""
继承数据
代码
class 子类(父类):
def __init__(self,参数列表):
super().__init__(参数列表)
self.自身实例变量 = 参数
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
# 1. 子类没有构造函数,可以直接使用父类的
# s01 = Student()
# 2. 子类有构造函数,会覆盖父类构造函数(好像他不存在)
# 所以子类必须通过super()调用父类构造函数
s01 = Student("小明", 24, 100)
print(s01.name)
print(s01.age)
print(s01.score)
定义
重用现有类的功能,并在此基础上进行扩展。
说明:子类直接具有父类的成员(共性),还可以扩展新功能。
优点
一种代码复用的方式。
缺点
耦合度高:父类的变化,直接影响子类。
练习一
"""
小明请保洁打扫卫生
1. 识别对象
小明 保洁
2. 分配职责
通知 打扫
3. 建立交互
小明调用保洁的打扫方法
要求:使用三种写法实现,说出不同的语义.
"""
# 写法一:小明每次请一个新保洁
"""
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()
"""
# 写法二:小明请自己的保洁
"""
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()
"""
# 写法三:小明请家政服务(参数 保洁)
class Client:
def __init__(self, name=""):
self.name = name
def notify(self, household_service):
print(self.name, "发出通知")
household_service.cleaning()
class Cleaner:
def cleaning(self):
print("保洁打扫卫生")
xm = Client("小明")
bj = Cleaner()
xm.notify(bj)
练习二
"""
1. 玩家攻击敌人,敌人受伤(播放动画)
2. 玩家(攻击力)攻击敌人(血量),
敌人受伤(播放动画,血量减少)
3. 敌人(攻击力)还能攻击玩家(血量),
玩家受伤(碎屏,血量减少)
"""
# 1. 类与类调用
# class Player:
# def attack(self, emeny):
# emeny.damage()
#
# class Enemy:
# def damage(self):
# print("播放受伤动画")
#
# p01 = Player()
# e01 = Enemy()
# p01.attack(e01)
# 2. 调用时增加数据 玩家(攻击力) -攻击力-> 敌人(血量)
"""
class Player:
def __init__(self, atk=0):
self.atk = atk
def attack(self, emeny):
print("玩家攻击敌人")
emeny.damage(self.atk)
class Enemy:
def __init__(self, hp):
self.hp = hp
def damage(self, value):
print("播放受伤动画")
self.hp -= value
print("敌人血量是", self.hp)
p01 = Player(50)
e01 = Enemy(100)
p01.attack(e01)
p01.attack(e01)
"""
# 3.
class Player:
def __init__(self, hp, atk):
self.hp = hp
self.atk = atk
def attack(self, emeny):
print("玩家攻击敌人")
emeny.damage(self.atk)
def damage(self, value):
print("碎屏")
self.hp -= value
print("敌人血量是", self.hp)
class Enemy:
def __init__(self, hp, atk):
self.hp = hp
self.atk = atk
def damage(self, value):
print("播放受伤动画")
self.hp -= value
print("敌人血量是", self.hp)
def attack(self, player):
print("敌人攻击玩家")
player.damage(self.atk)
p01 = Player(500, 50)
e01 = Enemy(100, 10)
p01.attack(e01)
e01.attack(p01)
练习三
"""
创建子类:狗(跑),鸟类(飞)
创建父类:动物(吃)
体会子类复用父类方法
体会 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()
# 类型 与 类型 的关系
print(issubclass(Animal, Dog))
# 对象 与 类型 的关系
print(isinstance(b01, Animal))
# 狗对象 与 动物类型 相同
print(type(d01) == Animal)
练习四
"""
创建父类:车(品牌,速度)
创建子类:电动车(电池容量,充电功率)
创建子类对象并画出内存图。
"""
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)