zoukankan      html  css  js  c++  java
  • 初识面向对象(Day17-Day18)

    人狗大战的游戏

    你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢?

    你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色

    def Person(name,sex,hp,ad):
        self = {'name':name,'sex':sex,'hp':hp,'ad':ad}
    return dict
    
    def Dog(name,kind,hp,ad):
       self = {'name': name, 'sex': kind, 'hp': hp, 'ad': ad}
    return dict

    上面两个方法相当于造了两个模子,游戏里的每个人和每条狗都拥有相同里的属性。游戏开始,你根据一个人或一只狗传入的具体信息来塑造一个具体的人或者狗,怎么生成呢?

    alex = Person('a_sb','不祥',50,50)
    chen = Dog('旺财','teddy',50,40)
    boss_jin = Person('金老板','',60,60)

    两个角色对象生成了,狗和人还有不同的功能呀,狗会咬人,人会打狗,对不对? 怎么实现呢,。。想到了, 可以每个功能再写一个函数,想执行哪个功能,直接 调用 就可以了,对不?

    def attack(dog):
        print('%s攻击%s' % (self['name'], dog['name']))
    
    
    def bite(person):
        print('%s咬%s' % (self['name'], person['name']))
    
    attack(chen)
    bite(alex)

    上面的功能实现的简直是完美!

    但是仔细玩耍一会,你就不小心干了下面这件事

    boss_jin = Person('金老板','',60,60)
    bite(boss_jin) #把人的对象传给了狗的方法

    事实 上,从你写的代码上来看,这并没出错。很显然,人是不能调用狗的功能的,但在你的程序例没有做限制,如何在代码级别实现这个限制呢?

    ef Person(name,sex,hp,ad):
        self = {'name':name,'sex':sex,'hp':hp,'ad':ad}
        def attack(dog):
            print('%s攻击%s' % (self['name'], dog['name']))
            dog['hp'] -= self['ad']
        self['attack'] = attack
        return self
    
    def Dog(name,kind,hp,ad):
        self = {'name': name, 'sex': kind, 'hp': hp, 'ad': ad}
        def bite(person):
            print('%s咬%s' % (self['name'], person['name']))
            person['hp'] -= self['ad']
        self['bite'] = bite
        return self
    
    alex = Person('a_sb','不祥',50,50)
    chen = Dog('旺财','teddy',50,40)
    boss_jin = Person('金老板','',60,60)
    alex['attack'](chen)
    boss_jin['attack'](chen)
    chen['bite'](alex)

    面向对象编程

    类和对象

    1.类的概念:具有相同属性和技能的一类事物(抽象)。

    2.对象的概念:对一个类的具体描述(具体)。

    比如人类就是一个抽象的概念,有具体哪一个人有什么特征就是对象。

    使用面向对象的好处

    1.是的代码之间的角色关系更加明确。

    2.增强了代码的可扩展性

    3.规范了对象的属性和方法技能。

    面向对象的特点:结局的不确定性。

    面向对象的语法

    class Person:# 定义一个类
        静态变量 = 123 # 静态属性(变量),可以引用多个
        def f1(self): #动态属性(变量,方法),默认带一个参数selfprint(666)

    类的作用:

    1.属性引用

     1)引用静态属性的方式

          类名.__dict__[''静态属性],可以查看静态属性,但是不能修改。

    class Person:# 定义一个类
        静态属性 = 123 
        def f1(self): 
            print(666)
    print(Person.__dict__['静态属性']) 
    Person.__dict__['静态属性'] = 456
    print(Person.__dict__['静态属性']) # 报错,只能引用不能修改

       类名.静态属性  可以直接访问,可以修改。

    class Person:# 定义一个类
        静态属性 = 123 
        def f1(self): 
            print(666)
    print(Person.静态属性)
    Person.静态属性 = 456 #改变静态变量
    print(Person.静态属性)

        删除静态属性的方法:del 类名.静态属性

    class Person:# 定义一个类
        静态属性 = 123 
        def f1(self): 
            print(666)
    del Person.静态属性
    print(Person.__dict__['静态属性'])

    2)引用动态属性

       类名.方法名 查看这个方法的内存地址。

    类名.方法名(实参)调用了这个方法,必须传一个实参,这个实参传给了self。
    class Person:
        role = 'person'
        def f1(self):
            print(666)
    Person.f1(1) #666
    print(Person.f1) #<function Person.f1 at 0x00000054A5E83730>

    3)创造一个对象——实例化

      产生一个实例(对象)的过程叫实例化

      语法:对象=类名() 如:alex = Person()

      实例化过程:

      1.创造一个实例,将会作为一个实际参数。

      2.自动触发一个__init__的方法,并把实例以参数的形式传递给__init__方法。

      3.执行完__init__方法之后,会将self自动返回给alex。

    class Person:
        def __init__(self,name,sex,hp,ad):
            self.name = name #self 里存储的内容叫对象属性
            self.sex = sex
            self.hp = hp
            self.ad = ad
    
    alex = Person('a_sb','',1,5)
    alex.__dict__['name'] = 'alex' # 修改name
    print(alex.name)#查看属性:对象名.属性名
    备注:__init__方法:初始化方法,给一个对象添加一些基础属性的方法,一般情况下是针对self的赋值

    对象

    1.在类的内部,self是本类的一个对象。

    2.在类的外部,每一个对象都对应着一个名字,这个对象指向一个对象的内存空间。

    3.属性的调用:

      对象名.属性名

      对象名__dict__['属性名']

    4.方法的调用:

      类名.方法名(对象名)#方法中的self参数就指向这个对象。

      对象名.方法名()  #这样写相当于方法中的self参数就指向这个对象。

    
    
    class Person:
        role = 'person'
        def __init__(self,name,sex,hp,ad):
            self.name = name #self 里存储的内容叫对象属性
            self.sex = sex
            self.hp = hp
            self.ad = ad
        def attack(self):
            print('%s发起了一次攻击' % self.name)
    
    alex = Person('a_sb','',1,5)
    # Person.attack(alex)
    alex.attack()

    对象之间的交互

    class Person: # 定义一个人类
        role = 'person'# 人的角色属性都是人
        def __init__(self,name,sex,hp,ad): # 定义一个对象
            self.name = name #每一个角色都有自己的属性
            self.sex = sex
            self.hp = hp
            self.ad = ad
        def attack(self,dog): #给人类定义一个攻击的方法
            dog.hp -= self.ad
            print('%s攻击了%s,%s掉了%s点血' % (self.name,dog.name,dog.name,self.ad))
    
    class Dog: #定义一个狗类
        role = 'dog' #狗的角色属性都狗
        def __init__(self,name,kind,hp,ad):
            self.name = name # 狗的属性
            self.kind = kind
            self.hp = hp
            self.ad = ad
        def bite(self,person): # 给狗类定义一个咬方法
            person.hp -= self.ad
            print('%s咬了%s一口,%s掉了%s点血' % (self.name,person.name,person.name,self.ad))
    
    
    alex = Person('alex','',50,30) # 实例一个人
    ha2 = Dog('笨笨','二哈',80,50) # 实例一个狗
    alex.attack(ha2)
    print('%s还剩%s点血' % (ha2.name,ha2.hp))
    ha2.bite(alex)
    print('%s还剩%s点血' % (alex.name,alex.hp))

     类命名空间与对象、实例的命名空间

     对象的内存空间里只存储对象的属性,而不存储方法和静态属性。

     类的内存空间里存储方法和静态属性,为了节省内存,让多个对象去共享类中的资源。

    代码从上至下执行,在全局命名空间里创建一个类(Person)的名称空间,用来存储role、__init__、attack这些属性,调用类名时实例化一个对象,创建一个名称空间,self指向这个空间地址,对象的参数添加到这个空间,这个空间的内存地址返回给对象alex,名称空间内有一个类对象指针 指向类名,通过类对象指针找到类名称空间。

    # 类的命名空间:
    class Person:
        role = 'person'   # 静态属性
        def __init__(self,name,sex,hp,ad):
            self.name = name     # 对象属性 属性
            self.sex = sex
            self.hp = hp
            self.ad = ad
        def attack(self):
            self.hobby = 'girl'
            print('%s发起了一次攻击'%self.name)
    
    alex = Person('a_sb','不详',1,5)
    alex.attack()   # Person.attack(alex)
    alex ---> person  # alex如何找到person
    person实例化了alex
    
    alex.name # alex指向自己的内存空间,在自己的内存空间里找到name
    alex.attack # alex先找到自己的内存空间,再找到类对象指针,根据类对象指针找到类,再通过类找到attack

     对象的属性是独有的,静态属性和方法是共享的,对象使用名字先找自己内存空间里的,再找类的内存 空间里的。

    class Person:
        role = 'person'   # 静态属性
        def __init__(self,name,sex,hp,ad):
            self.name = name     # 对象属性 属性
            self.sex = sex
            self.hp = hp
            self.ad = ad
            self.attack = 'hahaha'
        def attack(self):
            self.hobby = 'girl'
            print('%s发起了一次攻击'%self.name)
    
    alex = Person('a_sb','不详',1,5)
    alex.attack() # 报错

    对象在接收一个属性时只能放在自己的内存空间里。

    class Person:
        role = 'person'   # 静态属性
        def __init__(self,name,sex,hp,ad):
            self.name = name     # 对象属性 属性
            self.sex = sex
            self.hp = hp
            self.ad = ad
            self.attack = 'hahaha'
        def attack(self):
            self.hobby = 'girl'
            print('%s发起了一次攻击'%self.name)
    
    alex = Person('a_sb','不详',1,5)
    boss_jin = Person('金老板','',10,20)
    alex.role = 'dog'
    print(alex.role) #dog
    print(boss_jin.role) #person
    class Person:
        money = [0] #列表在内存中开辟一个空间存储每个元素的地址,通过地址找到对应的值
        def __init__(self,name):
            self.name = name
        def work(self):
            print(self.name,'工作,赚了1000块钱')
            self.money[0] += 1000
    
    father = Person('father')
    mother = Person('mother')
    mother.work()
    father.work()
    print(Person.money) # 2000 没有改变类中的关系

    静态变量属性的修改:类名.静态变量名

    面向对象的实例

    计算圆的周长和面积:半径1,2,5,7,9

    from math import pi
    class Circle:
        def __init__(self,r):
            self.r = r
        def cal_area(self):
            return pi*self.r**2
        def cal_perimeter(self):
            return pi*self.r*2
    for i in range(1,10,2):
        c1 = Circle(i)
        print(c1.cal_area())
        print(c1.cal_perimeter())

     面向对象的组合用法:

     组合概念:一个类对象作为另一个类对象的属性,表示一种什么有什么的关系。

     为什么用组合:独立的对象不能发挥它的作用,必须依赖一个对象。

    人狗大战升级版之组合

    class Person:
        def __init__(self,name,sex,hp,ad):
            self.name = name
            self.sex = sex
            self.hp = hp
            self.ad = ad
            self.money = 0
        def attack(self,dog):
            dog.hp -= self.ad
            print('%s攻击了%s,%s掉了%s点血'% (self.name,dog.name,dog.name,self.ad))
        def pay(self):
            money = int(input('请输入您要充值的金额:'))
            self.money += money
            print('您的余额是%s' % self.money)
        def wear(self,weapon): #
            if self.money >= weapon.price:
                self.weapon = weapon # 武器类对象作为人类对象的一个属性
                self.money -= weapon.price
                print('购买成功,您已经顺利装备了%s' % weapon.name)
            else:
                print('余额不足,请充值。')
        def attack_with_weapon(self,dog):
            if 'weapon' in self.__dict__:
                self.weapon.skill(dog)
            else:
                print('请先装备武器')
    
    class Dog:
        def __init__(self,name,kind,hp,ad):
            self.name = name
            self.kind = kind
            self.hp = hp
            self.ad = ad
        def bite(self,person):
            person.hp -= self.ad
            print('%s咬了%s,%s掉了%s点血' % (self.name, person.name, person.name, self.ad))
    
    class Weapon: #定义一个武器类
        def __init__(self,name,price,ad,level): #武器类具有名字、价格、攻击力、品级的属性
            self.name = name
            self.price = price
            self.ad = ad
            self.level = level
        def skill(self,dog): # 武器的方法
            dog.hp -= self.ad
            print('%s受到了%s的伤害,%s掉了%s点血' % (dog.name,self.name,dog.hp,self.ad))
    
    alex = Person('sb','man',20,10)
    boss_jin = Person('金老板','',50,50)
    teddy = Dog('笨笨','teddy',150,100)
    nife = Weapon('',500,100,1)
    
    # alex.pay()
    # alex.wear(nife) # 装备了刀
    # print(alex.__dict__) #{'name': 'sb', 'ad': 10, 'weapon': <__main__.Weapon object at 0x0000006F587462B0>, 'hp': 20, 'sex': 'man', 'money': 0}
    # print(alex.weapon) # alex.weapon = nife
    # print(nife) #<__main__.Weapon object at 0x0000006F587462B0>
    # alex.weapon.skill(teddy)
    
    
    lst = ['攻击','充值','装备武器','使用武器攻击']
    while True:
        for index,value in enumerate(lst,1):
            print(index,value)
        num = int(input('请选择操作序号>>>'))
        if num == 1:
            alex.attack(teddy)
        elif num == 2:
            alex.pay()
        elif num == 3:
            print('装备前余额%s' % alex.money)
            alex.wear(nife)
            print('装备后余额%s' % alex.money)
        elif num == 4:
            alex.attack_with_weapon(teddy)
        else:
            print('无效的序号')

     组合实例:计算圆环的面积

    from math import pi
    class Circle:
        def __init__(self,r):
            self.r = r
        def cal_area(self):
            return pi*self.r**2
        def cal_perimeter(self):
            return pi*self.r*2
    class Ring:
        def __init__(self,r1,r2): #r1=5,r2=2
            self.r1 = Circle(r1) #圆的对象,实例化大圆
            self.r2 = Circle(r2) #圆的对象,实例化小圆
        def ring_area(self):
            return self.r1.cal_area() - self.r2.cal_area()
        def ring_perimeter(self):
            return self.r1.cal_perimeter()+self.r2.cal_perimeter()
    
    ring = Ring(5,2)
    print(ring.ring_area())
    
    
    
  • 相关阅读:
    HDOJ 1207 汉诺塔II
    [转]写代码的小女孩
    POJ Subway tree systems
    HDOJ 3555 Bomb (数位DP)
    POJ 1636 Prison rearrangement (DP)
    POJ 1015 Jury Compromise (DP)
    UVA 10003
    UVA 103 Stacking Boxes
    HDOJ 3530 Subsequence
    第三百六十二、三天 how can I 坚持
  • 原文地址:https://www.cnblogs.com/facestore/p/8796945.html
Copyright © 2011-2022 走看看