第五章 面向对象程序设计开发

面向过程:优点 复杂的问题流水话,进而简单化

                  缺点 一套流水线或者流程就是用来解决一个问题 不好改动

                   应用场景 一旦完成基本就很少改变的场景 ,著名的例子有Linx内核, git,以及Apache HTTPserver

面向对象  核心就是对象二字

                 优点 解决了程序的可扩展性,对某个对象单独修改,会立刻反应到整体,如对游戏中一个人物参数的特征和技能修改都很容易

                   缺点  容易过度设计 

                无法向面向过程的程序设计流水想式的可以很精确的预测问题的处理流程与结果,面向对象一旦开始就由对象之间交互解决问题,即使上帝也无法准确地预测结果于是我们经常看到对战类游戏新增一个游戏人物,在交战过程中极易出现阴霸的技能,一刀砍死三个人,这种情况就是无法准确预测的,只有对象之间交互才能准确地知道最终的结果

                  应用场景 需求经常变动的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方

                   面向对象的程序设计并不是全部,对于一个软件质量来说,面向对象的程序设计只是用来解决程序扩展性

类与对象

             类即是类别,种类,是面向对象设计最重要的概念,对象的特征与技能的结合体,而类是一系列对象相似的特征与技能的结合体

             在现实世界中 现有对象,再有类

             在程序中 务必先保证先定义类,后产生对象

ps

1 在程序中特征用变量标识,技能用函数标识

2 因类中最常见的无非是 变量和函数的定义

程序中的类

class OldboyStudent:

     school = 'oldboy'

    def learn(self):

        print('is learning)

  

    def eat(self):

        print('is learning')

    def sleep(self):

        print('is sleeping')

注意

1 类中可以有任意python代码,这些代码在类定义阶段便会执行

2 因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过OldboyStudent.__dict__查看

3 对于经典类来说我们可以通过该字典操作类名称空间的名字(新式类有限制),但python为我们提供了专门的.语法

4 点的访问属性的语法,类中定义的名字,都是类的属性

程序中类的用法

 .  专门用来访问属性,本质操作的就是__dict__

OldboyStudent.school #等于经典类的操作OldboyStudent.__dict__['school']
OldboyStudent.school='Oldboy' #等于经典类的操作OldboyStudent.__dict__['school']='Oldboy'
OldboyStudent.x=1 #等于经典类的操作OldboyStudent.__dict__['x']=1
del OldboyStudent.x #等于经典类的操作OldboyStudent.__dict__.pop('x')

程序中的对象

调用类,或称为实例化,得到对象

s1 = OldboyStudent()

s2 = OldboyStudent()

s3 = OldboyStudent()

如此 s1 s2 s3 都一样了,而这三者除了属性之外还有各种不同的属性,这就用到了__init__

注意 该方法是在对象产生之后才执行的,只用来为对象进行初始化操作,可以有任意代码,但以订不能有返回值

class OldboyStudent:

    ....

    def __init__(self,name,age,sex):

        self.name=name

        self.age=age

        self.sex=sex

.......

s1=OldboyStudent('马以财‘,’男‘,16) 先定义类产生空对象s1,然后调用OldboyStudent。__init__(s1,'马以财','男',16)

程序中对象的用法

执行__init__,s1.name=’马以财',很明显也会产生对象的名称空间

s1.__dict__

{'name':‘马以财’,'sex':'男’,'age':16}

s1.name s1.__dict__['name']

s1.name = '王大炮' s1.__dict__['name']='王大炮‘

del s1.name   s1.__dict__.pop('name')

__init__的方法:

方式一 为对象初始化自己独有的特征

class People:

    country='China'

    x=1

    def run(self):

        print('---->',self)

实例化出三个对象

obj1=People()

obj2=People()

obj3=People()

为对象定制自己独特的特征

obj1.name='egon'

obj1.age=18

obj1.sex='male'

obj2.name='lxx'

obj2.age=38

obj2.sex='female'

obj3.name='alex'

obj3.age=38

obj3.sex='female'

print(obj1.__dict__)

print(Peple.__dict__)

方式二 为对象初始化自己独特的特征

class People:

    country='China'

    x=1

    def run(self):

        print('---->',self)

实例化出三个对象

obj1=People()

obj2=People()

obj3=People()

为对定制自己独有的特征

def chu_shi_hua(obj,x,y,z):

    obj.name=x

    obj.age=y

    obj.sex=z

chu_shi_hua(obj1,'egon',18,'male')

chu_shi_hua(obj2,'lxx',38,'female')

chu_shi_hua(obj3,'alex',38,'female')

方式三 为对象初始化自己独有的特征

class People:

    country='China'

    x=1

    def chu_shi_hua(obj,x,y,z)

        obj.name=x

        obj.age=y

        obj.sex=z

    def run(self):

        print('----->',self)

obj1=People()

People.chu_shi_hua(obj1,'egon',18,'male')

obj2=People()

People.chu_shi_hua(obj2,'lxx',38,'female')

obj3=People()

People.chu_shi_hua(obj3,'alex',38,'female')

方式四 为对象初始化自己独有特征

class People:

    country='China' x=1

    def __init__(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male'
          obj.name = x

          obj.age = y

          obj.sex = z

      def run(self):

           print('----->', self)

obj1=People('egon',18,'male')  People.__init__(obj1,'egon',18,'male')

__init__方法

强调

 1 该方法内可以有任意python代码

2 一定不能有返回值

class People: country='China' x=1

    def __init__(obj, name, age, sex): #obj=obj1,x='egon',y=18,z='male'
        # if type(name) is not str:
            # raise TypeError('名字必须是字符串类型')
        obj.name = name

        obj.age = age

        obj.sex = sex

     def run(self):

          print('----->', self)

obj1=People('egon',18,'male')

obj1=People(3537,18,'male)

print(obj1.run)

obj1.run()   People.run(obj1)

print(People.run)

属性查找

类有两种属性  数据属性和函数属性

1.类的数据属性是所有对象共享的

2 .类的函数属性是绑定给对象用的

类的数据属性是所以对象共享的 id都一样

print(id(OldboyStudent.school)) print(id(s1.school)) print(id(s2.school)) print(id(s3.school)) ''' 4377347328 4377347328 4377347328 4377347328

类的函数属性是绑定给对象用的,obj.method称为绑定方法,内存地址都一样

id是python的实现机制,并不能真是反应内存地址,如果有内存地址,还是以内存地址为准

print(OldboyStudent.learn) print(s1.learn) print(s2.learn) print(s3.learn) ''' <function OldboyStudent.learn at 0x1021329d8> <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x1021466d8>> <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146710>> <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146748>> '''

在 obj.name会先从obj自己的名称空间里找name,找不到则到类中找,类也找不到就找父类,最后都找不到,就抛出异常

绑定到对象的方法的特殊之处

class OldboyStudent: school='oldboy'
    def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def learn(self): print('%s is learning' %self.name) #新增self.name def eat(self): print('%s is eating' %self.name) def sleep(self): print('%s is sleeping' %self.name) s1=OldboyStudent('李坦克','',18) s2=OldboyStudent('王大炮','',38) s3=OldboyStudent('牛榴弹','',78)

类中定义的函数(没有被任何装饰器装饰的)是类的函数属性,类可以使用,但必须遵循函数的传参规则有几个参数传几个参数

OldboyStudent.learn(s1) 李坦克 is learning

类中定义的函数,其实主要是给对象使用的,而且是绑定到对象的,虽然所以对象指向的都是相同的功能,但是绑定到不同的对象是不同的绑定方法

绑定到对象的方法的特殊之处在于,绑定给谁据由谁调用,就会将谁本身做第一个参数传给方法,即自动传值(方法__init__也是一个道理)

s1.learn() 等同于OldboyStudent.learn(s1)

绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self可以是任意名字,但是约定成写self

类即类型 python中一切皆为对象,且python3 中类与类型是一个概念,类型就是类

类型dict就是类dict

list

<class 'list'>

实例化的三个对l1,l2,l3

l1=list()

l2=list()

l3=list()

三个对象有是绑定方法append,相同的功能,但内存地址不同

l1.append

<built_in method append of list object at 0x10b482b48>

l2.append

<built_in method append of list object at 0x10b482b88>

操作绑定方法l1.append(3),就是在往l1添加3,绝对不会将3添加到l2

l1.append(3)

l1

[3]

l2

[]

调用类list.append(l3,111)等同与l3.append(111)

list.append(l3,111)

l3

[111]

对象之间的交互

class Garen :    定义英雄盖伦的类,不同玩家可以用它实例出自己英雄;

    camp='Demaciua' 所以玩家的英雄的阵营都是Demacia;

    def __init__(self,nickname,aggressivity=58,life_value=455): 英雄初始攻击力58

        self.nickname=nickname

        ....

        self.life_value=life_value #英雄都有自己的生命值;

     def attack(self,enemy):

            enemy.life_value-=self.aggressivity 根据自己攻击力,攻击敌人就见到敌人的生命值

仿照garen类再创建一个Riven类

class Riven:
    camp='Noxus'  #所有玩家的英雄(锐雯)的阵营都是Noxus;
    def __init__(self,nickname,aggressivity=54,life_value=414): #英雄的初始攻击力54;
        self.nickname=nickname  #为自己的锐雯起个别名;
        self.aggressivity=aggressivity #英雄都有自己的攻击力;
        self.life_value=life_value #英雄都有自己的生命值;
    def attack(self,enemy):   #普通攻击技能,enemy是敌人;
        enemy.life_value-=self.aggressivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值。

实例化出俩英雄

g1=Garen('草丛伦‘)

r1=Riven('锐雯雯’)

交互 锐雯攻击草丛伦 反之一样

g1.life_value

455

r1.attack(g1)

g1.life.value

401

garen_hero.Q()称为给garen_hero这个对象发送一条消息,让他去执行Q这个功能,类似的有

garen_hero.E()

garen_hero.R()

设计对战游戏

class Riven:

    camp='Noxus'

    def __init__(self,nickname,

                        aggressivity=54,

                         life_value=414,

                         money=1001,

                         armor=3):

        self.nickname=nickname

       ........

    def attack(self,enemy):
        damag_value=self.aggressivity-enemy.armor

        enemy.life_value-=damage_value

定义盖伦类

calss Garen:

    camp='Demacia'

    def __init__(self,nickname,

                       aggressivity=58,

                        life_value=455,

                        money=100

                         armor=10):

        self.aggressivity=aggressivity

         ......

   def attack(self,enemy):

       damage_value=self.aggressivity-enemy.armor

        enemy.life_value-=danage_value

定义装备:多兰之刃

class BlackCleaver:

    def __init__(self,price=475,aggrev=9,life_value=100):

        self.price=price

    ......

     def update(self,obj):

        obj.money-=self.price 减钱

        obj.aggressivity+=self.affrev 加攻击

        obj.life_value+=self.life_value 加生命值

     def fire(self,obj): 这是该装备的主动技能,喷火,烧死对方

        obj.life_value-=1000  假设火烧的攻击力是1000

测试交互

r1 = Riven(‘草丛论’)

g1=Garen('盖伦‘)

b1=BlackCleaver()

print(r1.aggressivity,r1.life_value,r1.money) r1的攻击力,生命值,护甲

if r1.money > b1.price:

    r1.b1=b1  这个用法叫组合

    b1.update(r1)

print(r1.aggressivity,r1.life_value,r1.money) r1的攻击力,生命值,护甲

print(g1.life_value)

r1.attack(g1) 普通攻击

print(g1.life_value)

r1.b1.fire(g1) 用装备攻击

print(g1.life_value) g1的生命值小于0就死

原文地址:https://www.cnblogs.com/mayicai/p/9162971.html