4.2-类空间问题-类之间关系
类空间问题-类之间关系
类的空间问题
添加类的对象属性
class A:
def __init__(self, name):
self.name = name
def func(self, sex):
self.sex = sex
# 类外面:
obj = A('黑色利穆')
obj.age = 25
print(obj.__dict__)
# {'name': '黑色利穆', 'age': 25}
# 类内部:
obj = A('黑色利穆')
obj.func('男')
print(obj.__dict__)
# {'name': '黑色利穆', 'sex': '男'}
# 对象的属性不仅可以在__init__里添加,也可以在类的其他方法或者类的外面添加
添加类的静态属性
class A:
def __init__(self, name):
self.name = name
def func1(self, sex):
self.sex = sex
def func2(self):
A.bbb = 'ccc'
# 类外部:
A.aaa = 'heise'
print(A.__dict__)
# 类内部
A.func2(123)
print(A.__dict__)
# 类的属性不仅可以在类内部添加,也可以在类的外部添加
对象如何找到类的属性
class Human:
mind = '头脑'
language = '语言'
def __init__(self, name, sex):
self.name = name
self.sex = sex
def work(self):
print('需要工作')
obj = Human('黑色利穆', '男')
'''
具体过程:
obj = Human()
1.实例化一个对象,产生一个对象空间,此时这个对象空间不是空的,而是有一个类对象指针(相当于指示牌);
2.自动执行__init__方法,将对象空间传给self;
3.执行__init__代码,将对象空间封装属性;
Huamn类的名称空间:
mind = '头脑'
language = '语言'
def __init__(self, name, sex): 方法:函数地址:function 0x0000001ABCDFE
self.name = name
self.sex = sex
def work(self): 方法:函数地址:function 0x000000BCEFS
对象空间:
1:产生对象空间,并有一个类对象指针;
2:执行__init_-方法,给对象封装属性;
name = '黑色利穆'
sex = '男'
'''
# 对象查找属性的顺序:先从对象空间找 ---- 类空间找 ----- 父类空间找 ---- .......
# 类名查找属性的顺序:先从本类空间找 ---- 父类空间找 ---- .......
# 查找顺序都是单向不可逆 ,类名不可能找到对象的属性;
类与类之间的关系
类和对象都是对世界中的所有事物进行归类,事物之间存在着相应关系。类与类之间也存在着关系:在面向对象中,类与类存在着以下关系:
- 依赖关系;
- 关联关系;
- 组合关系;
- 聚合关系;
- 实现关系;
- 继承关系;
依赖关系
需求:天气天热了,大象想要进入冰箱;大象负责整个啥时间的掌控,冰箱被大象操作;
# 先写出两个类,一个大象类,一个冰箱类
class Elphant:
def __init__(self, name):
self.name = name
def open(self):
pass
def close(self):
pass
class Refrigerator:
def open_door(self):
print('冰箱门被打开了')
def close_door(self):
print('冰箱门被关上了')
# 冰箱功能很简单,只会开门,关门。但是大象并不是,大象开门需要找个冰箱,然后开冰箱门。接着进去,再关上冰箱门。注意:关的这个冰箱门必须和开的冰箱门是同一个冰箱;但是,大象是有更换冰箱的权利的,也可以想进入哪个冰箱进入哪个冰箱:
class Elphant:
def __init__(self, name):
self.name = name
def open(self, obj1):
print('大象打开冰箱门')
obj1.open_door()
def close(self, obj1):
print('大象关闭冰箱门')
obj1.close_door()
class Refrigerator:
def open_door(self):
print('冰箱门被打开了')
def close_door(self):
print('冰箱门被关上了')
elphant1 = Elphant('大象一')
haier = Refrigerator()
elphant1.open(haier)
elphant1.close(haier)
# 动作的发起主体是大象。
# 依赖关系:将一个类的对象或者类名传给另一个类的方法使用;
# 此时:大象和冰箱就是依赖关系。我需要用你,但你不属于我。这种关系是最弱的;
关联,聚合,组合关系
这三个关系代码上写法一样,含义不一样;
- 关联关系:两种事物必须是互相关联的,但是在某些特殊情况下可以更改和更换;
- 聚合关系:属于关联关系中的一种特例:重点是XX和XX聚合成XX。各自有搁置的声明周期;
- 组合关系:属于关联关系中的一种特例:组合关系比聚合还要紧密;一毁全毁;
组合关系:将一个类的对象封装到另一个类的对象的属性中,就叫组合;
关联关系:
男女朋友关系:男人关联着女朋友,女人关联着男朋友。这两种关系可以是相互的,也可以是单方面的;
class Boy:
def __init__(self, name, girlFriend=None):
self.name = name
self.girlFriend = girlFriend
def have_diner(self):
if self.girlFriend:
print(f'{self.name}和{self.girlFriend}一起吃晚饭')
else:
print('单身,咱不吃')
class Gril:
def __init__(self, name):
self.name = name
nan1 = Boy('白色利穆')
nan1.have_diner() # 单身,咱不吃
# 找到女朋友了
nan1.girlFriend = '小漂亮'
nan1.have_diner() # 白色利穆和小漂亮一起吃晚饭
class Boy:
def __init__(self, name, girlFriend=None):
self.name = name
self.girlFriend = girlFriend
def have_diner(self):
if self.girlFriend:
print(f'{self.name}和{self.girlFriend.name}一起吃晚饭')
else:
print('单身,咱不吃')
class Gril:
def __init__(self, name):
self.name = name
# 红色利穆生下来就有娃娃亲
nv2 = Gril('红漂亮')
nan2 = Boy('红色利穆', nv2)
nan2.have_diner()
# 红色利穆和红漂亮一起吃晚饭
# 长大后就分手了
nan2.girlFriend = None
nan2.have_diner()
# 单身,咱不吃
# 此时Boy和Girl两个类之间就是关联关系。两个类的对象紧密联系着,其中给一个没有了,另一个就孤独呢。
# 关联关系就是我需要你,你也属于我;
练习:
学校与老师之间的关系
# 老师属于学校,必须有学校才可以工作
class School:
def __init__(self, name, address):
self.name = name
self.address = address
class Teacher:
def __init__(self, name, school):
self.name = name
self.school = school
sc1 = School('北京大学', '北京市海淀区颐和园路5号')
sc2 = School('清华大学', '北京市海淀区双清路30号')
sc3 = School('北京师范大学', '北京市海淀区新街口外大街19号')
te1 = Teacher('黑色利穆', sc1)
te2 = Teacher('白色利穆', sc2)
te3 = Teacher('红色利穆', sc3)
print(te1.school.name)
print(te2.school.name)
print(te3.school.name)
但是学校也依赖老师,所有老师学校应该相互依赖
# 老师属于学校,必须有学校才可以工作
class School:
def __init__(self, name, address):
self.name = name
self.address = address
self.teacher_list = []
def append_teacher(self, teacher):
self.teacher_list.append(teacher)
class Teacher:
def __init__(self, name, school):
self.name = name
self.school = school
sc1 = School('北京大学', '北京市海淀区颐和园路5号')
sc2 = School('清华大学', '北京市海淀区双清路30号')
sc3 = School('北京师范大学', '北京市海淀区新街口外大街19号')
te1 = Teacher('黑色利穆', sc1)
te2 = Teacher('白色利穆', sc2)
te3 = Teacher('红色利穆', sc3)
print(te1.school.name)
print(te2.school.name)
print(te3.school.name)
sc1.append_teacher(te1)
sc1.append_teacher(te2)
sc1.append_teacher(te3)
for teacher in sc1.teacher_list:
print(teacher.name)
# 当逻辑上出现,我需要你,你还得属于我。这种逻辑,就是关联关系,这种关系比依赖关系要紧密;
# 组合关系和聚合关系,代码上没什么差别;
设计一个游戏人物,实例化几个对象让几个游戏人物实现互殴的效果;
class Gamerole:
def __init__(self, name, ad, hp):
self.name = name
self.ad = ad
self.hp = hp
def attack(self, p1):
p1.hp -= self.ad
print(f'{self.name}攻击{p1.name}, {p1.name}掉了{self.ad}血, 还剩{p1.hp}血')
gailun = Gamerole('盖伦', 10, 200)
yasuo = Gamerole('亚索', 30, 100)
# 盖伦攻击亚索
gailun.attack(yasuo)
gailun.attack(yasuo)
# 亚索攻击盖伦
yasuo.attack(gailun)
yasuo.attack(gailun)
游戏也进行了一会了,双方都出了武器,武器也是一个类。武器类包含的对象也有很多。所以写一个武器类;
class Gamerole:
def __init__(self, name, ad, hp):
self.name = name
self.ad = ad
self.hp = hp
def attack(self, p1):
p1.hp -= self.ad
print(f'{self.name}攻击{p1.name}, {p1.name}掉了{self.ad}血, 还剩{p1.hp}血')
class Weapon:
def __init__(self, name, ad):
self.name = name
self.ad = ad
def weapon_attack(self, p1, p2):
p2.hp = p2.hp - self.ad - p1.ad
print(f'{p1.name} 用 {self.name} 攻击了{p2.name}, {p2.name}还剩{p2.hp}血')
gailun = Gamerole('盖伦', 10, 200)
yasuo = Gamerole('亚索', 30, 100)
# 用武器攻击对方:
brick = Weapon('板砖', 10)
brick.weapon_attack(gailun, yasuo)
# 盖伦 用 板砖 攻击了亚索, 亚索还剩80血
# 武器攻击发起动作是人,所以brick不能是武器对象,所以进行修改
class Gamerole:
def __init__(self, name, ad, hp):
self.name = name
self.ad = ad
self.hp = hp
def attack(self, p1):
p1.hp -= self.ad
print(f'{self.name}攻击{p1.name}, {p1.name}掉了{self.ad}血, 还剩{p1.hp}血')
def equip_weapon(self, wea):
self.wea = wea # 组合,给一个对象封装一个属性,该属性是另一个类的对象
class Weapon:
def __init__(self, name, ad):
self.name = name
self.ad = ad
def weapon_attack(self, p1, p2):
p2.hp = p2.hp - self.ad - p1.ad
print(f'{p1.name} 用 {self.name} 攻击了{p2.name}, {p2.name}还剩{p2.hp}血')
# 实例化四个对象,两个人物,两把武器
gailun = Gamerole('盖伦', 10, 200)
yasuo = Gamerole('亚索', 30, 100)
brick = Weapon('板砖', 10)
endless = Weapon('无尽', 50)
# 给人物装备武器对象
gailun.equip_weapon(brick)
yasuo.equip_weapon(endless)
# 开始攻击
gailun.wea.weapon_attack(gailun, yasuo)
yasuo.wea.weapon_attack(yasuo, gailun)
# 这就是组合,只要人物.equip_weapon这个方法,那么人物就封装了一个武器对象,再利用武器对象调用其类中的weapon_attack方法;
'''
1.创建三个游戏人物:分别是:
武大,男,20,攻击力ad为20,血量200
武二,男,18,攻击力ad为60,血量500
金莲,女,19,攻击力ad为40,血量为150
2.创建三个游戏武器,分别是:
扁担,ad为20
拳套,ad为80
饭碗,ad为50
3.创建三个游戏摩托车,分别是:
小踏板,速度60迈
摩托车,速度80迈
欧米伽,速度200迈
完成系列需求(利用武器打人掉的血量为武的ad + 人的ad)
1.武大骑着小踏板开着60迈的车行驶在赛道上;
2.武二骑着摩托车开着80迈的车行驶在赛道上;
3.金莲骑着欧米伽开着200迈的车行驶在赛道上;
4.武大赤手空拳打了武二20滴血,武二还剩xx血;
5.武二赤手空拳打了金莲60滴血,金莲还剩xx血;
6.金莲用饭碗打了武二一饭碗,武二还剩xx血;
7.金莲用拳套打了武大一拳套,武大还剩xx血;
8:武大骑着小踏板打了骑着摩托车的武二一扁担,武二哭了;
9:金莲骑着欧米伽打了骑着摩托车的武二一饭碗,武二哭了;
'''
class Roles:
def __init__(self, name, sex, age, ad, hp, motor=None):
self.name = name
self.sex = sex
self.age = age
self.ad = ad
self.hp = hp
self.motor = motor
def ride_motor(self):
if self.motor:
print(f'{self.name}骑着{self.motor.name}开着{self.motor.speed}迈的车行驶在赛道上.')
else:
print(f'{self.name}没车')
def role_attack(self, r2):
r2.hp -= self.ad
print(f'{self.name}赤手空拳打了{r2.name}{self.ad}滴血,{r2.name}还剩{r2.hp}血')
def equip_weapon(self, wea):
self.wea = wea
class Weapon:
def __init__(self, name, ad):
self.name = name
self.ad = ad
def weapon_attack(self, r1, r2):
r2.hp = r2.hp - self.ad - r1.ad
print(f'{r1.name}用{self.name}打了{r2.name}一{self.name},{r2.name}还剩{r2.hp}血')
def role_ride_weapon(self, r1, r2):
print(f'{r1.name}骑着{r1.motor.name}打了骑着{r2.motor.name}的{r2.name}一{self.name},{r2.name}哭了')
class Motor:
def __init__(self, name, speed):
self.name = name
self.speed = speed
mo1 = Motor('小踏板', 60)
mo2 = Motor('摩托车', 80)
mo3 = Motor('欧米伽', 200)
ro1 = Roles('武大', '男', 20, 20, 200, mo1)
ro2 = Roles('武二', '男', 18, 60, 500, mo2)
ro3 = Roles('金莲', '女', 19, 40, 150, mo3)
we1 = Weapon('扁担', 20)
we2 = Weapon('拳套', 80)
we3 = Weapon('饭碗', 50)
ro1.ride_motor() # 武大骑着小踏板开着60迈的车行驶在赛道上.
ro2.ride_motor() # 武二骑着摩托车开着80迈的车行驶在赛道上.
ro3.ride_motor() # 金莲骑着欧米伽开着200迈的车行驶在赛道上.
ro1.role_attack(ro2) # 武大赤手空拳打了武二20滴血,武二还剩480血
ro2.role_attack(ro3) # 武二赤手空拳打了金莲60滴血,金莲还剩90血
ro3.equip_weapon(we3)
ro3.wea.weapon_attack(ro3, ro2) # 金莲用饭碗打了武二一饭碗,武二还剩390血
ro3.equip_weapon(we2)
ro3.wea.weapon_attack(ro3, ro1) # 金莲用拳套打了武大一拳套,武大还剩80血
ro1.equip_weapon(we1)
ro1.wea.role_ride_weapon(ro1, ro2) # 武大骑着小踏板打了骑着摩托车的武二一扁担,武二哭了
ro3.equip_weapon(we3)
ro3.wea.role_ride_weapon(ro3, ro2) # 金莲骑着欧米伽打了骑着摩托车的武二一饭碗,武二哭了