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 = '男'         
'''
# 对象查找属性的顺序:先从对象空间找   ----   类空间找  ----- 父类空间找 ---- .......
# 类名查找属性的顺序:先从本类空间找   ----   父类空间找 ----  .......
# 查找顺序都是单向不可逆 ,类名不可能找到对象的属性;

类与类之间的关系

类和对象都是对世界中的所有事物进行归类,事物之间存在着相应关系。类与类之间也存在着关系:在面向对象中,类与类存在着以下关系:

  1. 依赖关系;
  2. 关联关系;
  3. 组合关系;
  4. 聚合关系;
  5. 实现关系;
  6. 继承关系;

依赖关系

需求:天气天热了,大象想要进入冰箱;大象负责整个啥时间的掌控,冰箱被大象操作;

# 先写出两个类,一个大象类,一个冰箱类
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)

# 动作的发起主体是大象。
# 依赖关系:将一个类的对象或者类名传给另一个类的方法使用;
# 此时:大象和冰箱就是依赖关系。我需要用你,但你不属于我。这种关系是最弱的;

关联,聚合,组合关系

这三个关系代码上写法一样,含义不一样;

  1. 关联关系:两种事物必须是互相关联的,但是在某些特殊情况下可以更改和更换;
  2. 聚合关系:属于关联关系中的一种特例:重点是XX和XX聚合成XX。各自有搁置的声明周期;
  3. 组合关系:属于关联关系中的一种特例:组合关系比聚合还要紧密;一毁全毁;

组合关系:将一个类的对象封装到另一个类的对象的属性中,就叫组合;

关联关系:

男女朋友关系:男人关联着女朋友,女人关联着男朋友。这两种关系可以是相互的,也可以是单方面的;

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)  # 金莲骑着欧米伽打了骑着摩托车的武二一饭碗,武二哭了
posted @ 2020-12-05 16:36  黑色利穆  阅读(129)  评论(0编辑  收藏  举报