python面向对象:类空间,对象空间, 组合
一. 类空间,对象空间
1. 类空间,对象空间
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
而类有两种属性:静态属性和动态属性
- 静态属性就是直接在类中定义的变量
- 动态属性就是定义在类中的方法
其中类的数据属性是共享给所有对象的,用类名是找不到对象属性的
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性. 在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常.
查询顺序:
对象.属性 : 先从对象空间找,如果找不到,再从类空间找,再找不到,再从父类找...
类名.属性 : 先从本类空间找,如果找不到,再从父类找....
class Person: animal = '高级动物' soul = '有灵魂' language = '语言' def __init__(self, country, name, sex, age, hight): self.country = country self.name = name self.sex = sex self.age = age self.hight = hight def eat(self): print('%s吃饭' % self.name) def sleep(self): print('睡觉') def work(self): print('工作') p1 = Person('菲律宾', 'alex', '未知', 42, 175) p1.animal = '禽兽' # 通过对象不能改变,只能引用类中的静态变量, 所以修改的不是类中的animal,而是对象p1自己添加了animal属性. print(p1.animal) # 禽兽 先查找对象里有没有animal属性,如果没有,再去类中查找. print(Person.animal) # 高级动物 # print(Person.name) #报错,无法用类名查找对象的属性
计算对象实例化的次数
class Lei: num = 0 def __init__(self, name, sex): self.name = name self.sex = sex Lei.num = Lei.num + 1 # 要想使用类中的静态变量,必须要用'类名.'去使用 def func(self): print(self.name, self.sex) obj1 = Lei('alex', '男') obj2 = Lei('good', '女') obj3 = Lei('better', '男') print(Lei.num) # 3
二. 组合
组合: 给一个类的对象封装一个属性,这个属性是另一个类的对象.
通过例题来看一下什么是组合
模拟英雄联盟写一个游戏人物的类 要求: (1)创建一个 Game_role的类. (2) 构造方法中给对象封装name,ad(攻击力),hp(血量).三个属性. (3) 创建一个attack方法,此方法是实例化两个对象,互相攻击的功能: 例: 实例化一个对象 盖伦,ad为10, hp为100 实例化另个一个对象 剑豪 ad为20, hp为80 盖伦通过attack方法攻击剑豪,此方法要完成 '谁攻击谁,谁掉了多少血, 还剩多少血'的提示功能.
class Game_role: def __init__(self, name, ad, hp): self.name = name self.ad = ad self.hp = hp def attack(self, g): g.hp = g.hp - self.ad # 剑豪剩余的血为剑豪的总血减去盖伦的攻击 print('%s攻击%s,%s掉了%s血, 还剩%s血' % (self.name, g.name, g.name, self.ad, g.hp)) g1 = Game_role('盖伦', 10, 100) # 实例化第一个对象 g2 = Game_role('剑豪', 20, 80) # 实例化第二个对象 g1.attack(g2) # g1调用方法attack,并把g2传给方法attack里的参数'g' # 盖伦攻击剑豪,剑豪掉了10血, 还剩70血 print(g2.hp) # 70
要增加武器(刀棍道等), 需要增加一个类(武器名称,攻击力). 结果要求显示为 : '谁用什么武器攻击谁,谁掉了多少血, 还剩多少血'
class Game_role: def __init__(self, name, ad, hp): self.name = name self.ad = ad self.hp = hp def attack(self, g): g.hp = g.hp - self.ad # 剑豪剩余的血为剑豪的总血减去盖伦的攻击 print('%s攻击%s,%s掉了%s血, 还剩%s血' % (self.name, g.name, g.name, self.ad, g.hp)) def armament_weapon(self, wea): self.wea = wea # 给角色封装一个新的属性(武器) class Weapon: def __init__(self, name, ad): self.name = name self.ad = ad def fight(self, g1, g2): g2.hp = g2.hp - self.ad print('%s 用%s攻击%s,%s 掉了%s血,还剩%s血' \ % (g1.name, self.name, g2.name, g2.name, self.ad, g2.hp)) g1 = Game_role('盖伦', 10, 100) g2 = Game_role('剑豪', 20, 80) w1 = Weapon('斧头', 30) g1.armament_weapon(w1) # 把武器的属性传给Game_role类里的armament_weapon方法 print(g1.wea) # 其实就是w1 g1.wea.fight(g1, g2) # g1.wea.fight() = w1.fight() print(g2.hp) #50
无限的我,现在才开始绽放,从东边的第一缕阳光到西边的尽头