Python21期 day6 之面向对象

面向对象VS面向过程

面向过程的程序设计的核心是过程(流水线思维),过程即解决问题的步骤,面向过程就好比一条流水线,考虑周全什么时候处理什么东西

优点:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可

缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身

面向对象的程序设计的核心是对象(上帝式思维)

优点:解决程序的扩展性,对某一个对象单独修改,会立刻反映到整个体系中

缺点:可控性差

面向对象编程可以使程序的维护和扩展变得简单,并且可以提高程序开发效率

名词:类、对象、实例、实例化

类:具有相同特征的一类事物

对象/实例:具体的某一个事物

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

初始类和对象

Python中一切皆为对象,类型的本质就是类。用变量表示特征,函数表示技能,因而具有相同特征和技能的一类事物就是类,对象则是这一类事物中具体的一个

#声明函数
def functionName(args):
    函数体


#声明类
'''
class 类名:
    类体
'''

#创建一个类
class Data:
    pass
class Person:   #定义一个人类
    role = 'person'  #人的角色属性都是人
    def walk(self):  #人都可以走路,也就是有一个走路方法,也叫动态属性
        print("person is walking...")

类的两种作用:属性引用和实例化

属性引用(类名.属性)

class Person:    #定义一个人的类
    role = 'person'    #人的角色属性是人
    def walk(self):    #人可以走路,也就是有一个走路方法
        print('person is walking...')


print(Person.role)    #查看人的role属性
print(Person.walk)    #引用人的走路方法,注意这里不是调用

实例化:类名加括号就是实例化,会自动触发__init__函数的运行

class Person:
    role = 'person'
    def __init__(self,name):
        self.name = name    #每一个角色都有自己的昵称

    def walk(self):    #人可以走路,也就是有一个走路方法
        print('person is walking...')

print(Person.role)
print(Person.walk)

实例化的过程就是类---->对象的过程

原本只有一个Person类,在这个过程中,产生了一个egg对象,有自己的名字、攻击值和生命值

语法:对象名=类名(参数)

egg = Person('egon')    #类名()就等于在执行Person.__init__()
#执行完__init__()就会返回一个对象。这个对象类似一个字典,存着属于这个人本身的一些属性和方法
查看属性和调用方法
print(egg.name)    #查看属性,对象名.属性名
print(egg.walk())    #调用方法,对象名.方法名()

关于self

self:在实例化时自动将对象/实例本身传给__init__的第一个参数,默认是用self

类属性的补充

一、定义类的属性存在哪了?两种方法查看
dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值

二、特殊的类属性
类名.__name__    #类的名字(字符串)
类名.__doc__    #类的文档字符串
类名.__base__# 类的第一个父类(在讲继承时会讲)
类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)

回到咱们的人狗大战:现在我们需要对我们的类做出一点点改变
人类除了可以走路之外,还应该具备一些攻击技能。

class Person:
    role = 'person'

    def __init__(self,name,hp,dps):
        self.name = name    #角色的昵称
        self.hp = hp         #角色的攻击力
        self.dps = dps        #角色的生命值

    def attack(self,dog):
        dog.dps -= self.hp
        #人可以攻击狗,这里狗也是一个对象
        #人攻击狗,那么狗的生命值就是根据人的攻击力而下降

对象是关于类而实际存在的一个例子,即实例

对象/实例只有一个作用:属性引用

egg = Person('egon',10,1000)
print(egg.name)
print(egg.hp)
print(egg.dps)

当然也可以引用一个方法,因为方法也是一个属性,只不过是一个类似函数的属性,也叫动态属性。引用动态属性不是执行这个方法,更想调用方法和调用函数是一样的,都需要在后面加上括号
#面向对象小结 ---- 定义及调用的固定模式

class 类名:
    def __init__(self,参数1,参数2):
        self.对象的属性1 = 参数1
        self.对象的属性2 = 参数2

    def 方法名(self):pass

    def 方法名2(self):pass


对象名 = 类名(1,2)    #对象就是实例,代表一个具体的东西
                            #类名():类名+括号就是实例化一个类,相当于调用了__init__方法
                        #括号里传参数,参数不需要传self,其他与init中的形参一一对应
                        #结果返回一个对象

对象.对象的属性1        #查看对象的属性,直接用 对象名.属性名
对象名.方法名()        #调用类中方法,直接用对象名.方法名()
练习:在终端输出如下信息

小明,10岁,男,上山去砍柴
小明,10岁,男,开车去东北
小明,10岁,男,最爱大保健
老李,90岁,男,上山去砍柴
老李,90岁,男,开车去东北
老李,90岁,男,最爱大保健


class Person:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def action(self,hoby):
        self.hoby = hoby
        print('%s,%d,%s,%s'%(self.name,self.age,self.sex,self.hoby))

egon = Person('小明',10,'man')
li = Person('老李',90,'man')

egon.action('上山去砍柴')
egon.action('开车去东北')
egon.action('最爱大保健')

li.action('上山去砍柴')
li.action('开车去东北')
li.action('最爱大保健')

对象间的交互

现在我们已经有一个人类了,通过给人类一些具体的属性我们就可以拿到一个实实在在的人。
现在我们要再创建一个狗类,狗就不能打人了,只能咬人,所以我们给狗一个bite方法。
有了狗类,我们还要实例化一只实实在在的狗出来。
然后人和狗就可以打架了。现在我们就来让他们打一架吧!

创建一个狗的类

class Dog:
    role = 'dog'

    def __init__(self,name,bread,hp,dps):
        self.name = name  # 每一只狗都有自己的昵称;
        self.breed = breed  # 每一只狗都有自己的品种;
        self.hp = hp    # 每一只狗都有自己的攻击力;
        self.dps = dps     ## 每一只狗都有自己的生命值;

    def bite(self,people):
        people.dps -= self.hp

ha2 = Dog('二愣子','哈士奇',10,1000) #创造了一只实实在在的狗ha2
交互 egon打ha2

print(ha2.dps)
egg.attack(ha2)    #egg打了ha2

完整的代码

class Person:
    def __init__(self,name,hp,dps,sex):
        self.name = name
        self.hp  = hp
        self.dps = dps
        self.sex = sex
        self.bag = []
    def attack(self,dog):
        dog.hp -= self.dps
        print('%s打了%s,%s掉了%s点血,剩余%s点血' %(self.name,dog.name,dog.name,self.dps,dog.hp))

class Dog:
    def __init__(self,name,kind,hp,dps):
        self.name = name
        self.kind = kind
        self.hp = hp
        self.dps = dps
    def bite(self,person):
        person.hp -= self.dps
        print('%s咬了%s,%s掉了%s点血,剩余%s点血' %(self.name,person.name,person.name,self.dps,person.hp))

alex = Person('alex',250,500,'man')
ha2 = Dog('小哈','藏獒',15000,200)

#掉用方式 -- 对象名.方法名
alex.attack(ha2)   #相当于Person.attack(alex)
ha2.bite(alex)
计算圆的面积和周长:

from match import pi

class Circle:
    def __init__(self,r):
        self.r = r

    def area(self):
        print( pi * self.r ** 2)

    def perimeter(self):
        print( 2 * self.r * pi)


circle = Circle(5)  #实例化一个圆
circle.area()    #计算圆的面积
circle.perimeter()  #计算圆的周长

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

创建一个类就会创建一个类的命名空间,用来存储类中定义的所有名字,这些名字称为类的属性

类有两种属性:静态属性和动态属性

  静态属性就是直接在类中定义的变量

  动态属性就是定义在类中的方法

其中类的数据属性是共享给所有对象的

>>>id(egg.role)
4341594072
>>>id(Person.role)
4341594072

类的动态属性是绑定到所有对象的

>>>egg.attack
<bound method Person.attack of <__main__.Person object at 0x101285860>>
>>>Person.attack
<function Person.attack at 0x10127abf8> 

创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性

在obj.name会从obj自己的命名空间找name,找不到则去类中找,类找不到就找父类,最后找不到抛出异常

面向对象的组合用法

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

class Weapon:
    def prick(self,obj): # 这是该装备的主动技能,扎死对方
        obj.life_value -= 500  # 假设攻击力是500


class person:
    def __init__(self,name):
        self.name = name
        self.weapon = Weapon()    #给角色绑定一个武器

egg  = Person('egon')
egg.weapon.price()
#egg组合了一个武器的对象,可以直接egg.weapon来使用组合类中的所有方法

 

面向对象的三大特性

继承

继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,父类又可以成为基类或超类,新建的类称为派生类或子类

 

posted @ 2018-05-18 11:11  叫你你敢答应么  阅读(96)  评论(0)    收藏  举报