空间角度研究类 类与类之间的关系
-
对象操作对象属性
class A():
address = '沙河'
def __init__(self, name):
self.name = name
def func(self): # 给对象封装一个属性
if self.name == 'ls':
self.age = 100
obj = A('ls') #实例化一个对象
# 类的外部给对象封装属性
obj.sex = '男'
print(obj.__dict__) #查看对象空间的属性
# 类的内部,使用方法 给对象封装属性
obj.func()
print(obj.__dict__) #查看对象空间的属性
###总结:
# 对象的属性不仅可以在`__init__`里面添加,还可以在类的其他方法或者类的外面添加。 -
类名操作类中的属性
class A():
address = '沙河'
def __init__(self, name):
self.name = name
def func1(self):
A.country = '中国'
obj = A('ls') #实例化一个对象
## 类 外部给类封装属性
A.temp='39℃' # 给类添加一个属性
print(A.__dict__) #查看类名称空间的属性
## 类 内部调用函数封装属性
A.func1(obj) # 由于类要调用类中方法必须传递参数给self.在这里可以把obj对象作为参数传递给self,相当于对象调用了这个方法(obj.func1())
print(A.__dict__) #查看类名称空间的属性
###总结:
# 类的属性不仅可以在类内部添加,还可以在类的外部添加。 -
类对象指针
所谓指针:当实例化生成对象时,会产生一个对象指针,存在对象名称空间. 用于指向类空间
class A():
class_attr='123'
def __init__(self,name):#实例化过程自动执行__init__方法,给对象封装属性,还封装一个类对象指针
self.name=name
a=A() #实例化对象 a
a.class_attr # a是对象的名称空间,不存在class_attr属性. 这时类对象指针指向类名称空间,类名称空间存在class_attr属性.a对象就能获得class_attr属性.
#总结:
# 类对象指针就是存在对象中,用于指向回生成对象的这个类. -
对象取值顺序
对象查找属性的顺序:先从对象空间------> 类空间------> 父类空间
-
类名取值顺序
类名查找属性的顺序:先从本类空间-------> 父类空间
二丶类与类的关系
-
依赖关系:
依赖关系 (主从关系) 将一个类的类名,或者对象传给另一个类的方法中
class Elephant():
def __init__(self, name):
self.name = name
def open(self, ref): # 依赖关系, ref是形参,接收另一个类生成的对象
print(f'{self.name}🐘象 要 开门')
ref.open_door() # ref是一个对象.可以调用这个对象内包含的一切,通过.的方式
def close(self, ref): # 依赖关系, ref是形参,接收另一个类生成的对象
print(f'{self.name}🐘象 要 关门')
ref.close_door() # ref是一个对象.可以调用这个对象内包含的一切,通过.的方式
class Fridge():
def __init__(self, name):
self.name = name
def open_door(self):
print(f'{self.name} 冰箱门被打开了...')
def close_door(self):
print(f'{self.name}冰箱门被关上了')
ele = Elephant('QQ') #实例化一个对象
ref = Fridge('美菱') # 实例化一个对象
ele.open(ref) # 依赖关系, ref 是另一个类生成的对象 传给了ele对象的open方法
ele.close(ref) # 同上 -
组合关系(关联组合聚合)
将一个类的对象,封装成另一个对象的属性
class Boy:
def __init__(self, name):
self.name = name
def meet(self, girl_friend=None):
self.girl_friend = girl_friend # 组合,把g1对象封装为b1对象的属性
print(girl_friend) # 女孩类生成对象的内存地址 <__main__.Gril object at 0x000001975E844630>
def have_dinner(self):
if self.girl_friend:
print(f'{self.name} 请女朋友{self.girl_friend.name}吃饭')
print(f'{self.name} 的女朋友年龄是{self.girl_friend.age}')
self.girl_friend.shopping(self) # 回传.g1对象中也可调用b1对象的一切
else:
print('没有女的 .不吃饭')
class Gril:
def __init__(self, name, age):
self.name = name
self.age = age
def shopping(self,wu):
print(f'{self.name} 和 {wu.name} 一起去购物')
b1 = Boy('赵四')
g1 = Gril('李柳柳', 45)
b1.meet(g1) # 组合 将一个类的对象,封装成另一个对象的属性
b1.have_dinner()
### 总结
### 一个类的方法只能有此类的对象去调用
### 一个类的方法的第一个self只接收此类的对象
-
######## 组合 和 依赖 ########
class GameRole(): # 游戏角色类
def __init__(self, name, ad, hp):
self.name = name
self.ad = ad
self.hp = hp
def equip_Weapons(self,weapon):
self.weapon=weapon # 组合, 把武器类对象传给角色类对象,封装成角色对象的属性
class Weapons():
def __init__(self,name,ad):
self.name=name
self.ad=ad
def weapons_attack(self,role1,role2): #依赖
role2.hp -= self.ad + role1.ad
print(f'{role1.name} use {self.name} attack {role2.name},{role2.name}掉了{self.ad + role1.ad}血,剩余{role2.hp}')
gailun=GameRole('盖伦',20,100) # 生成游戏角色对象
fengnan=GameRole('风男',15,100)
dbj=Weapons('大宝剑',20) # 生成武器对象
td=Weapons('太刀',18)
## 上面需要解决的问题: 发起武器攻击的发起者应该是人类,而不是great_sword武器对象.
## 但是weapon_attack只能有Weapon类的对象去调用.
gailun.equip_Weapons(dbj) #组合
gailun.weapon.weapons_attack(gailun,fengnan) # 依赖 :把角色对象传递给武器类的weapons_attack方法中
gailun.weapon.weapons_attack(gailun,fengnan) # 依赖 : -