初识面向对象

python学习网 2019-05-31 20:25:02

初识面向对象

初识面向对象:

  • 一种新的编程思路

  • 一些概念

  • 一些语法

    一.楔子:
        # 游戏公司
            # 人狗大战
        # 人 :
            # 名字 性别 职业 等级 血条 武器 攻击力
            # 技能 : 搓澡
        # 狗 :
            # 名字 品种 血条 攻击力
            # 技能 : 舔
    
            alex = {
                'name':'alex',
                'sex':'不详',
                'job':'搓澡工',
                'level':0,
                'hp':'250',
                'weapon':'搓澡巾',
                'ad':1
            }
    
            小白 = {
                'name':'小白',
                'kind':'泰迪',
                'hp':5000,
                'ad':249
            }
    
            # 1.你怎么保证所有的玩家初始化的时候都拥有相同的属性
            # 2.每来一个新的玩家,我们都自己手动的创建一个字典,然后向字典中填值
            # 3.人物和狗的技能如何去写
    
             def Person(name,sex,job,hp,weapon,ad,level=0):  # 人模子
                 dic = {
                     'name': name,
                     'sex': sex,
                     'job': job,
                     'level': level,
                     'hp': hp,
                     'weapon': weapon,
                     'ad': ad
                 }
                 return dic
             alex = Person('alex','不详','搓澡工',250,'搓澡巾',1)
             print(alex)#{'name': 'alex', 'sex': '不详', 'job': '搓澡工', 'level': 0, 'hp': 250, 'weapon': '搓澡巾', 'ad': 1}
             wusir = Person('wusir','male','法师',500,'打狗棍',1000)
             print(wusir)#{'name': 'wusir', 'sex': 'male', 'job': '法师', 'level': 0, 'hp': 500, 'weapon': '打狗棍', 'ad': 1000}
    
    
             def Dog(name,kind,hp,ad):           #狗
                 dic = {
                     'name': name,
                     'kind': kind,
                     'hp': hp,
                     'ad': ad
                 }
                 return dic
             小白 = Dog('小白','泰迪',5000,249)
             print(小白)#{'name': '小白', 'kind': '泰迪', 'hp': 5000, 'ad': 249}
             小金 = Dog('小金','柯基',10000,499)
             print(小金)#{'name': '小金', 'kind': '柯基', 'hp': 10000, 'ad': 499}
    
        #给人和狗添加技能,并且要保证人物和狗只能调用各自的功能:将技能函数放入函数中
             def Person(name,sex,job,hp,weapon,ad,level=0):  # 人模子
                 def 搓(dog):  #传参dog = 小白;小白是一个字典。   # 函数不是一个公用的函数 是一个有归属感的函数
                     dog['hp'] -= dic['ad']    #包含闭包:在内层函数引用了外层函数的非全局变量
                     print(f"{dic['name']}攻击了{dog['name']},{dog['name']}掉了{dic['ad']}点血")
    
                 dic = {
                     'name': name,
                     'sex': sex,
                     'job': job,
                     'level': level,
                     'hp': hp,  #血条
                     'weapon': weapon,
                     'ad': ad,    #攻击力
                     'action':搓   #搓 为函数的内存地址
                 }
                 return dic
    
    
             def Dog(name,kind,hp,ad):           #狗
                 def 舔(person):  ## 函数不是一个公用的函数 是一个有归属感的函数
                     person['hp'] -= dic['ad']
                     print(f"{dic['name']}舔了{person['name']},{person['name']}掉了{dic['ad']}点血")
                 dic = {
                     'name': name,
                     'kind': kind,
                     'hp': hp,
                     'ad': ad,
                     'action':舔  #舔 为函数的内存地址
                 }
                 return dic
             alex = Person('alex','不详','搓澡工',250,'搓澡巾',1)  #执行Person()函数时,传参时没有传默认参数level,其他参数传入字典dic。当遇到函数定义def 搓(dog)的时候, 解释器只是把函数名读入内存。最后将dic返回给alex
    
             print(alex)#{'name': 'alex', 'sex': '不详', 'job': '搓澡工', 'level': 0, 'hp': 250, 'weapon': '搓澡巾', 'ad': 1, 'accction': <function Person.<locals>.搓 at 0x00000204F8609B70>}
    
             小白 = Dog('小白','泰迪',5000,249)
    
             print(小白)#{'name': '小白', 'kind': '泰迪', 'hp': 5000, 'ad': 249, 'action': <function Dog.<locals>.舔 at 0x00000204F8609BF8>}
    
        # #调用技能函数:
             alex['action'](小白)  #因为有内层函数的内存地址,所以即使外层函数执行完了,依然可以通过 内存地址+()执行内层函数。  alex['action']即 <function Person.<locals>.搓 at 0x00000204F8609B70>
             小白['action'](alex)  #小白['action']  即<function Dog.<locals>.舔 at 0x00000204F8609BF8>
            #结果:
             alex攻击了小白,小白掉了1点血
             小白舔了alex,alex掉了249点血
    
    
    二.面向过程VS面向对象
    
        #面向过程:
         面向过程 : 想要一个结果 写代码 实现计算结果
         面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。
         优点是:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可。
         缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身。
         应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及ApacheHTTPServer等。
    
        #面向对象:
         面向对象开发 : 有哪些角色 角色的属性和技能 两个角色之间是如何交互的
         面向对象的程序设计的核心是对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。
         优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
         缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。
         应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方。
              复杂的 拥有开放式结局的程序 比较适合使用面向对象开发。如:游戏,购物
    
    
    三.类的相关知识:
    
        先来定义模子,用来描述一类事物:具有相同的属性和动作    
    
        # 从上到下加载类时,class一个缩进内的代码会执行,def内部的代码不执行。 只是加载了Person ,加载__init__,但__init__函数不会执行,。
         class Person:  #类名      类名+() 会自动调用类中的__init__方法
             def __init__(self,name,sex): #本行执行。但是本函数不调用不执行。类名+() 会自动调用类中的__init__方法
                 # 必须叫__init__这个名字,不能改变的,所有的在一个具体的人物出现之后拥有的属性都可以写在这里
                 self.name = name
                 self.sex = sex
             print('in Person')
         #结果: #不用调用Person 就可以执行
          in Person
    
    
        class Person:  #类名      类名+() 会自动调用类中的__init__方法
            def __init__(self,name,sex,job,hp,weapon,ad):  # 传参的时候 name = alex ,
                # 必须叫__init__这个名字,不能改变的,所有的在一个具体的人物出现之后拥有的属性都可以写在这里
                #下面的参数:用哪个参数,怎么去写,可以自己决定。想写多少个写多少个,不会因为上面只传了6个参数受限制
                self.name = name  #实际上是self.name = alex
                self.sex = sex
                self.job = job
                self.level = 0
                self.hp = hp
                self.weapon = weapon
                self.ad = ad
                # print(self,self.__dict__)
            # def 搓(self,):
        alex = Person('alex','不详','搓澡工',260,'搓澡巾',1) # alex 就是对象  alex = Person()的过程 是通过类获取一个对象的过程 - 实例化
        print(alex,alex.__dict__)#<__main__.Person object at 0x00000217D5DCFA20> {'name': 'alex', 'sex': '不详', 'job': '搓澡工', 'level': 0, 'hp': 260, 'weapon': '搓澡巾', 'ad': 1}
    
        wusir = Person('wusir','male','法师',500,'打狗棍',1000)   # wusir = Person()  self作为返回值,返回给alex/wusir
        print(wusir,wusir.__dict__)
    
    # 属性的查看,修改,增加,删除
         print(alex.name)#alex  等价于 print(alex.__dict__['name'])    属性的查看
         alex.name = 'alexsb'        # 属性的修改
         print(alex.name)#alexsb
    
         alex.money = 1000           # 属性的增加
         print(alex.money)#1000
    
         print(alex.__dict__)#{'name': 'alexsb', 'sex': '不详', 'job': '搓澡工', 'level': 0, 'hp': 260, 'weapon': '搓澡巾', 'ad': 1, 'money': 1000}
         del alex.money           # 属性的删除
         print(alex.__dict__)#{'name': 'alexsb', 'sex': '不详', 'job': '搓澡工', 'level': 0, 'hp': 260, 'weapon': '搓澡巾', 'ad': 1}
    
    
    面向对象:
    # 了解一些名词:类、对象、实例、实例化
      在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是‘类’,对象是则是这一类事物中具体的一个。
    
         [1]类:具有相同特征的一类事物。类是具有相同属性和相似功能的一类事物
            #类 是一个大范围 是一个模子 它约束了事物有哪些属性 但是不能约束具体的值
            # 一个模子\大的范围\抽象
            # 你可以清楚的知道这一类事物有什么属性,有什么动作
            # 但是你不能知道这些属性具体的值
          例如:Person是一个类 :alex wusir都是这个类的对象
    
        [2]对象===实例(对象和实例是同一个)具体的某一个事物
          #对象 是一个具体的内容 是模子的产物 它遵循了类的约束 同时给属性赋上具体的值
            # 给类中所有的属性填上具体的值就是一个对象或者实例
            # 只有一个类,但是可以有多个对象都是这个类的对象
    
         [3]实例化:类——>对象的过程
              # 实例化所经历的步骤:实例 = 类名+()
                 1. 类名+()之后的第一个事儿 :(首先)开辟一块儿内存空间
                 2.调用 __init__方法,把开辟的空间的内存地址传递给self参数,从而传递到函数内部
                 3.init方法中一般完成 : 把属性的值存储在self的空间里 - 对象的初始化。所有的这一个对象需要使用的属性都需要和self关联起来
                 4.执行完init中的逻辑之后,self变量会自动的被返回到调用处(发生实例化的地方),即self这个地址会作为返回值,返回给"实例"
    
         [4] 方法 : 定义在类里的函数,并且还带有self参数
    
         [5] 实例变量 : self.名字
    
    
         [6]关于空间
    
          类有一个空间,存储的是定义在class中的所有名字
    
          每一个对象拥有自己的空间,通过对象名.__dict__就可以查看这个对象的属性和值
    
          修改列表\字典中的某个值,或者是对象的某一个属性,都不会影响这个字典\列表\对象所在的内存空间
    
    
    
    
    
    class Person:  #类名      类名+() 会自动调用类中的__init__方法
        def __init__(self,name,sex,job,hp,weapon,ad):
            # 必须叫__init__这个名字,不能改变的,所有的在一个具体的人物出现之后拥有的属性都可以写在这里
            self.name = name     ## 对象的属性/实例变量
            self.sex = sex
            self.job = job
            self.level = 0
            self.hp = hp
            self.weapon = weapon
            self.ad = ad
            # print(self,self.__dict__)
        def 搓(self,dog):        ## 方法,拥有一个必须传的参数-->self对象
            dog.hp -= self.ad
            print(f"{self.name}搓了{dog.dog_name},{dog.dog_name}掉了{self.ad}点血,剩余{dog.hp}点血")
    
    
    # dog类 实现狗的属性 名字 品种 血量 攻击力 都是可以被通过实例化被定制的
    class Dog:
        def __init__(self,name,blood,aggr,kind):
            self.dog_name = name
            self.hp = blood
            self.ad = aggr
            self.kind = kind
        def 舔(self,person):  # 狗舔了人,人掉血  哪一个对象(小白)调用的这个方法,这个方法的第一个参数self就是那个对象
            if person.hp >= self.ad:
                person.hp -= self.ad
            else:
                person.hp = 0
            print(self,self.__dict__)#<__main__.Dog object at 0x000001F4934DFBE0> {'dog_name': '小白', 'hp': 4999, 'ad': 249, 'kind': '泰迪'}
            print(f"{self.dog_name}舔了{person.name},{person.name}掉了{self.ad}点血,剩余{person.hp}点血")
    
    
    alex = Person('alex','不详','搓澡工',260,'搓澡巾',1) # alex 就是对象  alex = Person()的过程 是通过类获取一个对象的过程 - 实例化
    # print(alex,alex.__dict__)#<__main__.Person object at 0x00000217D5DCFA20> {'name': 'alex', 'sex': '不详', 'job': '搓澡工', 'level': 0, 'hp': 260, 'weapon': '搓澡巾', 'ad': 1}
    
    小白 = Dog('小白',5000,249,'泰迪')#  对象\实例 = 类名+() -->  实例化的过程  对象和实例是同一个
    # print('alex : ',alex)
    # print(小白,小白.__dict__)#<__main__.Dog object at 0x000001F4934DFBE0> {'dog_name': '小白', 'hp': 5000, 'ad': 249, 'kind': '泰迪'}
    # print(小白.dog_name)#小白
    
    alex.搓(小白)#此处传的参数,永远比接收的参数少一个。
    小白.舔(alex)#哪一个参数(小白,小金)调用这个方法,就把那一块内存空间作为self值传出去,print(self,self.__dict__)拿到的就是那个self的值。
    #结果:
    # alex搓了小白,小白掉了1点血,剩余4999点血
    # 小白舔了alex,alex掉了249点血,剩余11点血
    
    
    
    

阅读(2097) 评论(0)