初识面向对象1

一、引言

1.1、锲子

  人、狗大def Person(name,hp,ad,sex): # 模子

def Person(name,hp,ad,sex):   # 模子   
  dic = {'name':name,'blood':hp,'attack':ad,'sex':sex} def fight(dog): # 攻击 属于人 # 狗掉血,就是人的攻击力 dog['blood'] -= dic['attack'] print('%s打了%s,%s掉了%s血' % (dic['name'], dog['name'], dog['name'], dic['attack'])) dic['fight'] = fight return dic def Dog(name,hp,ad,kind): dic = {'name': name, 'blood': hp, 'attack': ad, 'kind': kind} def bite(person): # 咬 属于狗 person['blood'] -= dic['attack'] print('%s咬了%s,%s掉了%s血' % (dic['name'], person['name'], person['name'], dic['attack'])) dic['bite'] = bite return dic # 互相打 alex = Person('alex',20,1,'不详') print(alex) hei = Dog('小黑',3000,10,'哈士奇') print(hei) alex['fight'](hei) hei['bite'](alex)
小结:
  • 通过两个模子 捏出两个具体的角色
  • 抽象 :只能知道有哪些属性
  • 具体 :可以描述他的属性的值的
  • 给两个特定的属于特定角色的方法 设置了他的使用范围
  • 让其他角色不能随意调用属于固定角色的方法
  • 写代码时注意字典赋值时的缩进以及掉血和的攻击的字典属性,容易出错

1.2、面向对象和面向过程

面向过程:

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

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

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

  应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

面向对象

  核心设计思想:对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。

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

  缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。

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

  面向对象编程可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。

  面向对象的一些名词:

    类:具有相同特征的一类事物(人、狗、老虎)

    对象/实例:具体的某一个事物(隔壁阿花、楼下旺财)

    实例化:类——>对象的过

 1.3、类和对象

  1、python中一切皆为对象,类型的本质就是类。

  2、在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是‘类’,对象是则是这一类事物中具体的一个

二、类和对象的相关知识:

2.1类的相关知识

1、类或函数的声明:

函数的声明:
def functionName(args):
     '函数文档字符串'
      函数体 

类的声明:
'''
class 类名:
    '类的文档字符串'
    类体
'''

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

 2、类的两种作用,属性引用与实例化

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


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

 3、查看属性与调用方法:

print(小白.name)     #查看属性直接 对象名.属性名
print(小白.walk())   #调用方法,对象名.方法名()

  类的补充

一:我们定义的类的属性到底存到哪里了?有两种方式查看
dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值

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

  小结

 1.类名可以调用所有定义在类中的名字
    变量
    函数名 
2、对象名 可以调用所有定义在对象中的属性
在init函数中和self相关的 调用函数的,且调用函数的时候,会把当前的对象当做第一个参数传递给self
3、self 在实例化时自动将对象/实例本身传给__init__的第一个参数,你也可以给他起个别的名字,但是正常人都不会这么做,约定俗称。

 2.2对象的相关知识

1、引言

class Person:  # 定义一个人类
    role = 'person'  # 人的角色属性都是人

    def __init__(self, name, aggressivity, life_value):
        self.name = name  # 每一个角色都有自己的昵称;
        self.aggressivity = aggressivity  # 每一个角色都有自己的攻击力;
        self.life_value = life_value  # 每一个角色都有自己的生命值;

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

2、属性的应用

静态属性:
egg = Person('egon',10,1000) print(egg.name) print(egg.aggressivity) print(egg.life_value)
动态属性:
print(egg.attack) #如果要执行函数,必须要加括号

3、用函数来模拟类

def Person(*args,**kwargs):
    self = {}
    def attack(self,dog):
        dog['life_value'] -= self['aggressivity']

    def __init__(name,aggressivity,life_value):
        self['name'] = name
        self['aggressivity'] = aggressivity
        self['life_value'] = life_value
        self['attack'] = attack

    __init__(*args,**kwargs)
    return self

egg = Person('egon',78,10)
print(egg['name'])

 

4、小结

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   #查看对象的属性,直接用 对象名.属性名 即可
对象名.方法名()     #调用类中的方法,直接用 对象名.方法名() 即可

三、对象之间的交互

1、认狗大战

class Person:  # 定义一个人类
    role = 'person'  # 人的角色属性都是人

    def __init__(self, name, aggressivity, life_value):
        self.name = name  # 每一个角色都有自己的昵称;
        self.aggressivity = aggressivity  # 每一个角色都有自己的攻击力;
        self.life_value = life_value  # 每一个角色都有自己的生命值;

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

class Dog:  # 定义一个狗类
    role = 'dog'  # 狗的角色属性都是狗

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

    def bite(self,people):
        # 狗可以咬人,这里的狗也是一个对象。
        # 狗咬人,那么人的生命值就会根据狗的攻击力而下降
        people.life_value -= self.aggressivity

egg = Person('egon',10,1000)  #创造了一个实实在在的人egg
ha2 = Dog('二愣子','哈士奇',10,1000)  #创造了一只实实在在的狗ha2
print(ha2.life_value)         #看看ha2的生命值
egg.attack(ha2)               #egg打了ha2一下
print(ha2.life_value)         #ha2掉了10点血

2、计算园的面积和周长

from math import pi

class Circle:
    '''
    定义了一个圆形类;
    提供计算面积(area)和周长(perimeter)的方法
    '''
    def __init__(self,radius):
        self.radius = radius

    def area(self):
         return pi * self.radius * self.radius

    def perimeter(self):
        return 2 * pi *self.radius


circle =  Circle(10) #实例化一个圆
area1 = circle.area() #计算圆面积
per1 = circle.perimeter() #计算圆周长
print(area1,per1) #打印圆面积和周长

 

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

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

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

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

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

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

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

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

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

3、总结

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

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

 五、面向对象的组合用法

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

 1、游戏中武器

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

class Person:  # 定义一个人类
    role = 'person'  # 人的角色属性都是人

    def __init__(self, name):
        self.name = name  # 每一个角色都有自己的昵称;
        self.weapon = Weapon()  # 给角色绑定一个武器;
        
egg = Person('egon')
egg.weapon.prick() 
#egg组合了一个武器的对象,可以直接egg.weapon来使用组合类中的所有方法

 

 2、圆环的面积和周长

rom math import pi

class Circle:
    '''
    定义了一个圆形类;
    提供计算面积(area)和周长(perimeter)的方法
    '''
    def __init__(self,radius):
        self.radius = radius

    def area(self):
         return pi * self.radius * self.radius

    def perimeter(self):
        return 2 * pi *self.radius


circle =  Circle(10) #实例化一个圆
area1 = circle.area() #计算圆面积
per1 = circle.perimeter() #计算圆周长
print(area1,per1) #打印圆面积和周长

class Ring:
    '''
    定义了一个圆环类
    提供圆环的面积和周长的方法
    '''
    def __init__(self,radius_outside,radius_inside):
        self.outsid_circle = Circle(radius_outside)
        self.inside_circle = Circle(radius_inside)

    def area(self):
        return self.outsid_circle.area() - self.inside_circle.area()

    def perimeter(self):
        return  self.outsid_circle.perimeter() + self.inside_circle.perimeter()


ring = Ring(10,5) #实例化一个环形
print(ring.perimeter()) #计算环形的周长
print(ring.area()) #计算环形的面积

 

六、总结

游戏大战进阶版

class Person:  # 定义一个人类
    role = 'person'  # 人的角色属性都是人

    def __init__(self, name, aggressivity, life_value, money):
        self.name = name  # 每一个角色都有自己的昵称;
        self.aggressivity = aggressivity  # 每一个角色都有自己的攻击力;
        self.life_value = life_value  # 每一个角色都有自己的生命值;
        self.money = money

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

class Dog:  # 定义一个狗类
    role = 'dog'  # 狗的角色属性都是狗

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

    def bite(self,people):
        # 狗可以咬人,这里的狗也是一个对象。
        # 狗咬人,那么人的生命值就会根据狗的攻击力而下降
        people.life_value -= self.aggressivity


class Weapon:
    def __init__(self,name, price, aggrev, life_value):
        self.name = name
        self.price = price
        self.aggrev = aggrev
        self.life_value = life_value

    def update(self, obj):  #obj就是要带这个装备的人
        obj.money -= self.price  # 用这个武器的人花钱买所以对应的钱要减少
        obj.aggressivity += self.aggrev  # 带上这个装备可以让人增加攻击
        obj.life_value += self.life_value  # 带上这个装备可以让人增加生命值

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

测试交互 :

lance = Weapon('长矛',200,6,100)
egg = Person('egon',10,1000,600)  #创造了一个实实在在的人egg
ha2 = Dog('二愣子','哈士奇',10,1000)  #创造了一只实实在在的狗ha2

#egg独自力战"二愣子"深感吃力,决定穷毕生积蓄买一把武器
if egg.money > lance.price: #如果egg的钱比装备的价格多,可以买一把长矛
    lance.update(egg) #egg花钱买了一个长矛防身,且自身属性得到了提高
    egg.weapon = lance #egg装备上了长矛

print(egg.money,egg.life_value,egg.aggressivity)

print(ha2.life_value)
egg.attack(ha2)   #egg打了ha2一下
print(ha2.life_value)
egg.weapon.prick(ha2) #发动武器技能
print(ha2.life_value) #ha2不敌狡猾的人类用武器取胜,血槽空了一半

 

posted @ 2019-04-19 18:27  与凯学习  阅读(79)  评论(0编辑  收藏  举报