• DAY15 面向对象初始


    初识面向对象

       在python之中,一切皆对象。面向对象编程(OOP)是一种编程思想,把对象作为编程的单元,使得程序更加容易拓展。

       面向对象编程的一些专业名词:

         类 :具有相同属性和功能的一类事物。

         对象/实例 :类的具体实现。

         实例化 :类--->对象的过程。

    类是什么?

        类:具有相同属性或者功能的一类事物。

    class A:
        name = 'he'   #属性(静态属性)/静态变量/静态字段
    
        def func1(self):  #动态属性/方法
            pass
    

         通过上面的代码,我们创建了一个类A,接下来我们来看看具体的定义:

       class :定义类的关键字,类似于def。

       name = ‘he’ :类的属性,又称为静态属性/静态字段/静态变量。

        def func1(self):pass  : 这个类似于函数的东西,在类中称为方法,也称为动态属性。

      总结:从上面我们可以得到,一个类主要有两部分组成,类的属性+类的方法

    类名的使用:操作类的属性

        首先,我们必须明白一个概念。类,是一个公共模型,是一个公共的框架。

    class Person:
        animal = '高级动物'             #类的属性
        walk_way = '直立行走'           
        language = '语言'
        
        def eat(self):                 #类的方法
            print('吃吃吃,喝喝喝')
        def work(self):
            print('人类都需要工作')
        
    

       如果知道一个类究竟有哪些属性以及方法?此时“__dict__”方法就能帮到我们。

          __dict__ :   查看类/对象中的所有属性以及方法,并返回一个字典。

    class Person:
        animal = '高级动物'
        walk_way = '直立行走'
        language = '语言'
        
        def eat(self):
            print('吃吃吃,喝喝喝')
        def work(self):
            print('人类都需要工作')
    
    
    #(1)通过__dict__方法查看类Person中的所有属性以及方法
    print(Person.__dict__)
    >>>
    {'__module__': '__main__', 'animal': '高级动物', 'walk_way': '直立行走', 'language': '语言', '__init__': <function Person.__init__ at 0x0000020F50318A60>, 'eat': <function Person.eat at 0x0000020F50318AE8>, 'work': <function Person.work at 0x0000020F50318B70>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    
    
    #(2) 返回的是一个字典,取个值看看。
    print(Person.__dict__['animal'])
    >>>
    高级动物
    
    #(3)既然能够取值,那么能否修改呢?
    Person.__dict__['animale'] = '低级动物‘
    >>>
    TypeError: 'mappingproxy' object does not support item assignment       #报错了
    

        总结:通过以上的例子,__dict__方法的使用方法如下:

          (1)__dict__方法能够以字典的方式,把类中的所有属性和方法返回回来。对于单个的值,可以通过__dict__[key]来查询,但是只能查不能修改。。

          (2)一般在工作中,__dict__方法只用在查询类的属性以及方法上,不进行其他操作。对于增删查改类中的某个属性,某个方法,可以用到万能的点"."。

        

          类中属性的查有两种方式:1.__dict__[属性名]    2.‘类名.属性名’

    class Person:
        animal = '高级动物'
        walk_way = '直立行走'
        language = '语言'
    
    #(1)通过__dict__查询animal的值
    print(Person.__dict__['animal'])
    >>>
    高级动物
    #(2)通过万能的点 print(Person.animal) >>> 高级动物

           

    #如果定义一个类中本没有的属性,那么就可以把新属性添加进去。
    Person.thinking = '思考'
    print(Person.__dict__)                        #thinking:思考 就会新添加进去。
    >>>
    {'__module__': '__main__', 'animal': '高级动物', 'walk_way': '直立行走', 'language': '语言', '__init__': <function Person.__init__ at 0x0000024D779689D8>, 'eat': <function Person.eat at 0x0000024D77968A60>, 'work': <function Person.work at 0x0000024D77968AE8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'thinking': '思考'}
    

            

    # 通过del语句删除类中的属性
    del Person.walk_way
    print(Person.walk_way)
    >>>
    AttributeError: type object 'Person' has no attribute 'walk_way'    #类中没有该属性

           

    #如果一个现有的属性,想更改他对应的值。
    Person.animal = '低等动物'
    print(Person.animal)
    >>>
    低等动物

    类名的使用:操作类的方法

       类中的方法,一般不直接通过类名来操作,而是通过对象来操作类的方法。

    #方法一:通过__dict__方法来执行类的方法(骚操作,不建议使用)
    Person.__dict__['work']('alex')
    >>>
    人类都需要工作
    
    #方法二:通过万能的点(不建议使用)
    Person.work('alex')
    >>>
    人类都需要工作
    

    对象是什么?

       对象:类的具体实现,类的实例化。

    #类的实例化
    he = Person()   #这样就实例化了一个对象,在内存空间中开辟了一个对象空间。

         看到这里,我们可能会比较懵圈,究竟怎么样产生的一个对象?接下来,__init__(self)特殊方法就该登场了。

    __init__()特殊方法

       __init__()方法的第一个参数必须是self,在类的实例化过程中执行。

    class Person:
        animal = '高级动物'
        walk_way = '直立行走'
        language = '语言'
    
        def __init__(self,name,age,eye):    #特殊方法,给对象封装属性。
            print(self)
            self.name = name                     #给对象增加一个属性
            self.age = age
            self.eye = eye
    
    
        def eat(self):
            print('吃吃吃,喝喝喝')
        def work(self):
            print('人类都需要工作')
    
    
    #此时,你会好奇,self这个参数究竟是何方神圣??于是,立马实例化一个对象
    he = Person('he',23,'small eye')      #实例化了一个对象he,手动把实参传入,self去哪了??
    print(he)
    >>>
    <__main__.Person object at 0x000002CC8FE0E128>
    <__main__.Person object at 0x000002CC8FE0E128>
    
    #两个内存地址是一样的,证明self就是he这个对象。
    

       类的实例化过程中其实有三个步骤:

      (1)执行类的实例化过程,会在内存中创建一个对象空间,其中有一个类对象指针,能够指向类的内存空间。

      (2)自动执行__init__()特殊方法,把对象空间自动传给self参数,其他所需参数需要手工传递。

      (3)执行__init__()方法的具体逻辑,给对象空间封装属性。

    对象操作对象空间

    he = Person('he',23,'small eye')    #实例化一个对象,he这个对象自动传给参数self,其他参数需要填入。
    print(he.__dict__)                       #查看对象空间的所有属性和方法
    >>>
    {'name': 'he', 'age': 23, 'eye': 'small eye'}
    
    #属性的查
    print(he.name)
    >>>
    he
    
    #属性的增
    he.sex = 'male'
    print(he.__dict__)
    >>>
    {'name': 'he', 'age': 23, 'eye': 'small eye', 'sex': 'male'}
    
    #属性的改
    he.eye = 'big eye'
    print(he.eye)
    >>>
    big eye
    
    #属性的删除
    del he.eye
    print(he.__dict__)
    >>>
    {'name': 'he', 'age': 23}

    对象操作类空间的属性以及方法

    #对象操作类空间的属性, 只能查看类中的属性,不能修改。
    print(he.animal)                  #类只能查看类中的属性
    he.animal = '低等动物'          #看似改变类的属性,其实就是给对象新增一个对象
    print(Person.animal)
    print(he.__dict__)
    >>>
    高级动物
    高级动物
    {'name': 'he', 'age': 23, 'eye': 'small eye', 'animal': '低等动物'}
    
    
    #对象操作类中的方法(推荐)
    he = Person('he',23,'small eye')
    he.eat()
    >>>
    吃吃吃。。
    

       问题一: 对象为什么能够调用类中的属性与方法?

       答:因为对象空间中存在着类对象指针,对象会先在对象空间中寻找,如果找不到,会到类空间中寻找。。

       问题二: 对象与对象之间能够互相调用吗?

       答:同一个类实例化出来的对象之间是不能互相调用的;但是不同类实例化出来的对象,可以互相调用。

       问题三: 如果给对象封装属性?

       答: 方式一:通过__init__()特殊方法,给对象封装属性。

          方式二:如果有特殊属性,在任何位置都可以增加。

    组合

      组合:给一个类的对象封装一个属性,这个属性是另一个类的对象。

      哔哔哔,现在有了一个新的需求,要求盖伦用它的大宝剑对亚索发起一个攻击,亚索也可以通过他的日本武士刀给盖伦来一刀。有了上面的经验,一瞬间~

    class GameRole:
        def __init__(self,name,ad,hp):
            self.name = name
            self.ad = ad
            self.hp = hp
    
        def attack(self,role):
            role.hp = role.hp - self.ad
            print('%s攻击了%s,%s掉了%s血,还剩%s血'%(self.name,role.name,role.name,self.ad,role.hp))
    
    p1 = GameRole('盖伦',20,500)
    p2 = GameRole('剑豪',100,200)
    
    class Weapon:
        def __init__(self,name,ad):
            self.name = name
            self.ad = ad
    
        def fight(self,role1,role2):
            role2.hp = role2.hp - self.ad
            print('%s用%s攻击%s,%s掉了%s血,还剩%s血'%(
                role1.name,
                self.name,
                role2.name,
                role2.name,
                self.ad,
                role2.hp
            ))
    
    w1 = Weapon('大宝剑',30)
    w2 = Weapon('武士刀',50)
    
    
    #一瞬间写完,然后执行:
    w1.fight(p1,p2)
    >>>
    盖伦用大宝剑攻击剑豪,剑豪掉了30血,还剩170血
    

      啪啪啪,一顿敲完,也运行成功了,自豪感油然而生~但是真的正确吗,静静的看一下,应该就能看到了端倪。有点不合常理啊,应该攻击的发起者是人类,但是现在却变成了武器对象。

      但是,角色对象和武器对象分属于两个不同的类。。能够通过一个类的对象访问另外一个类的方法吗?组合变能够做到。

    class GameRole:
        def __init__(self,name,ad,hp):
            self.name = name
            self.ad = ad
            self.hp = hp
    
        def attack(self,role):
            role.hp = role.hp - self.ad
            print('%s攻击了%s,%s掉了%s血,还剩%s血'%(self.name,role.name,role.name,self.ad,role.hp))
    
        def equipment(self,w):            
            self.weapon = w             #这就是组合,给一个类的对象封装一个属性,该属性的值是另一个类的 
                                                   对象
    
    
    p1 = GameRole('盖伦',20,500)
    p2 = GameRole('剑豪',100,200)
    
    class Weapon:
        def __init__(self,name,ad):
            self.name = name
            self.ad = ad
    
        def fight(self,role1,role2):
            role2.hp = role2.hp - self.ad
            print('%s用%s攻击%s,%s掉了%s血,还剩%s血'%(
                role1.name,
                self.name,
                role2.name,
                role2.name,
                self.ad,
                role2.hp
            ))
    
    w1 = Weapon('大宝剑',30)
    w2 = Weapon('武士刀',50)
    
     
    p2.equipment(w2)                   #即p2.weapen = w2,就能欧访问到为w2的内存地址。
    p2.weapon.fight(p2,p1)
    

      总结:

        组合的好处就是能够把一个类的对象与另一个类的对象产生关系,从而是一个类与另一个类产生关系。

      

          

     

  • 相关阅读:
    互联网秒杀设计
    生产者消费者模式实现
    Ping CAP CTO、Codis作者谈redis分布式解决方案和分布式KV存储
    VIM使用学习笔记 : 按键说明
    Cookie的有效访问路径
    简单的Cookie记录浏览记录案例
    认识Cookie和状态管理
    Java异常
    Java接口基础
    String常用方法
  • 原文地址:https://www.cnblogs.com/hebbhao/p/9526327.html
Copyright © 2020-2023  润新知