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
无限的我,现在才开始绽放,从东边的第一缕阳光到西边的尽头
原文地址:https://www.cnblogs.com/huangqihui/p/9360789.html