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())
    
    
    
  • 相关阅读:
    CSS 选择器
    HTML lable和fieldset
    html image和表格
    HTML a标签
    html 提交后台的标签
    HTML INPUT系列使用
    HTML内标签、换行
    HTML 头部详解
    单例模式
    const 指针的三种使用方式
  • 原文地址:https://www.cnblogs.com/facestore/p/8796945.html
Copyright © 2011-2022 走看看