zoukankan      html  css  js  c++  java
  • d20 面向对象

    面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。

    是将数据和处理数据的函数绑定到一起封装到对象中

    对象是特征与技能的结合体,基于面向对象设计程序

    例子: 把大象装进冰箱 ?

    面向过程:

    1.打开冰箱

    2.装入大象

    3.关闭冰箱

    面向对象:

    找个具有装大象的技能的对象

    在面向对象中程序员的角度发生改变,从具体的操作者变成了指挥者;

    强调:对象不是凭空产生的,需要我们自己设计

    优缺点

    优点:

    1.提高扩展性,当一个对象发生了修改时,对其他对象时没有任何影响的,对象之间相互独立,耦合度变得更低了

    2.提高复用性

    3.提高灵活性,如果某个对象发生变化,也不会影响其他的对象 , 扩展性

    缺点:

    1.可控性差,无法预知结果

    2.程序的复杂度高

    应用场景:

    对扩展性要求较高的程序

    面向过程编程思想

    优点:逻辑清晰,将复杂问题简单化,流程化,

    缺点:扩展性差,可维护性差,牵一发而动全身

    使用场景:

    对扩展性要求较低的程序例如:系统内核,git,计算器

    类和对象

    是OOP中的最核心的两个概念

    是一系列具有相同特征和行为的集合体,是一种抽象概念

    即类型,类别

    对象

    具备某种特征与行为的结合体,在程序中用变量来表示对象的特征,函数表示对象的技能,在生活中万物皆对象

    对象:将变量与函数结合在一起,形成一个整体

    也可以理解为:

    变量的作用是存储数据,函数的作用在处理数据

    对象是将数据与处理数据的函数绑定在一起

    编程思想不是某一个具体语言或技术 ,
    面向对象的语言:
    python,Java,C++,C#
    面向过程:
    C,ruby

    创建类与对象

    在python中,定义类通过class关键字:

    class Student:
        pass

    class 后面紧跟是类名,遵循python 编码规范,类名通常是大写开头的单词,多个单词时使用驼峰命名法

    大驼峰命名法
    class Student:
        pass
    小驼峰命名法
    class student:
        pass
    命名法

    创建对象的语法

    class Student:
        pass
    #创建对象,通过类名加()实例化产生一个对象
    p = Student()
    print(p)
    #实例化得到的内存地址  <__main__.Student object at 0x00000000022EC978>
    print(Student)
    #得到的类 <class '__main__.Student'>
    语法

    属性的写法

    属性可以写在类中 
    类中的属性,是所有对象公共的 
    
    也可以写在对象中 
    对象中的属性,是每个对象独特的(不一样的)
    
    
    如果类中和对象中存在同样的属性,先访问对象 如果没有在访问类 
    
    
    练习: 描述一个老师类 需要包含 一个公共属性和 一个独特的属性 
    
    class Teacher:
        school = "oldboy"
        
    t1 = Teacher()
    t1.name = "jack"
    t1.age = 28
    写法

    对象的属性操作

    对象是特征(属性)与行为(方法)的结合体

    其添加属性可以在创建对象后使用点语法(变量名加 . )比如为对象添加name属性

    class Student:
        pass
    
    #创建对象,通过类名加()实例化产生一个对象
    p = Student()
    print(p)
    print(Student)
    p.name = "Jerry"

    同样通过点语法来获取对象的属性值

    print(p.name)
    #输出 Jerry

    属性的增删改查

    增加属性 
    对象变量名称.属性名称 = 属性值
    
    删除属性
    del 对象的变量名称.属性名称 
    
    修改 
    对象.属性 = 新的值 
    
    查看属性  访问的是对象的所有属性 
    print(对象.__dict__)
    
    访问对象的类信息
    print(对象.__class__)
    
    访问对象的类名
    print(对象.__name__)

    初始化方法

    用于为对象的属性设置初始值的函数

    class Student:
        def __init__ (self,name):
            print("init run")
            self.name = name
    s1 = Student('李三')
    s2 = Student('王五')
    注意:该函数不能有任何返回值/.... 只能是None  规定如此..

    执行过程:

    在创建对象时Student("jack")会申请新的内存空间用于保存对象数据,接着自动调__init__函数

    __init__函数要求第一个参数必须是self,该参数表示需要被初始化的对象本身,这样就可以将name属性绑定到对象上,有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去:

    # p1 = Student()
    # 以上代码将抛出异常:TypeError: __init__() missing 1 required positional argument: 'name'
    p1 = Student("jack")
    # 输出 init run
    print(p1.name)
    # 输出 jack
    View Code
    总结:
    
    - init函数用于为对象属性设置初始值 
    - 在创建对象时会自动调用
    - 自动传入对象本身

    属性查找顺序

    可以将类中的内容都称之为属性,变量称为数据属性,函数就叫函数属性

    类中可以声明变量来表示数据属性,为Student类添加数据属性和函数属性

    class Student:
        school = "Tsinghua" #数据属性
        
        def say_hello(self):#函数属性
            print("hello i am a student")
        
        def __init__ (self,name): #初始化函数
            self.name = name
       
    属性

    也可以使用点语法在创建对象后为对象增加数据属性

    stu = Student("Maria")
    stu.age = 20

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

    创建对象后为增加的数据属性,是这个对象特有的,去其他对象没有关联

    查找顺序:

    优先查找对象自己的名称空间,如果没有则在类中找,如果类中也没有则到父类中找,直到找到为止,如果父类中也没有则抛出异常

    class Student:
        school = 'beidaokou'
        def __init__(self,name):
            self.name = name
            
    stu1 = Student("Jack")
    stu2 = Student("Rose")
    
    #1.类中的数据属性是所有对象共享的
    print(stu1.school)
    print(stu2.school)
    #输出均为 beidaokou
    
    #2.类中的数据属性访问的是同一块内存
    print(id(stu1.school))
    print(id(stu2.school))
    #输出 4470412656
    #输出 4470412656
    
    #3.类的函数属性是绑定给对象使用的,bound method称为绑定方法,每个对象的绑定方法内存地址不一样
    print(stu1.say_hello)
    print(stu2.say_hello)
    #输出 <bound method Student.say_hello of <__main__.Student object at 0x10cc405f8>>
    #输出 <bound method Student.say_hello of <__main__.Student object at 0x10cc40630>>
    
    
    #4.优先访问对象自己的名称空间 
    # 修改stu1的学习属性为北京大学 会在自stu1的名称空间增加school属性
    stu1.school = "Beijing"
    print(stu1.__dict__)
    print(stu2.__dict__)
    #输出 {'name': 'Jack', 'school': 'Beijing'}
    #输出 {'name': 'Rose'}
    
    #4.1再次查看学校属性
    print(stu1.school)
    print(stu2.school)
    #输出 Beijing
    #输出 Tsinghua
    
    #__dict__用于访问对象的名称空间 本质是一个字典类型数据,存储名称与值的映射关系
    查找

    绑定方法

    1.绑定到对象的方法:没有被任何装饰器装饰的方法。

    在类中定义的函数默认都是绑定到对象的方法

    特点:参数的第一个必须是self 表示当前对象本身,使用对象来调用,调用时会自动传入对象

    class Student:
        
        def __init__(self,name):
            self.name = name
         
        def say_hi(self):
            print("hello my name is %s" % self.name)
    绑定到对象

    2.绑定到类的方法:用classmethod装饰器装饰的方法。

    特点:参数的第一个必须是cls表示当前类本身,使用类名来调用,调用时会自动传入类

    class OldBoyStudent:
        school = "oldboy"
    
        def __init__(self,name):
            self.name = name
    
        @classmethod
        def show_school(cls):
            # print(self.school)
            print(cls)
    绑定到类
    什么时候绑定给对象:当函数逻辑需要访问对象中的数据时
    
    什么时候绑定给类:当函数逻辑需要访问类中的数据时

    非绑定方法

    用staticmethod装饰器装饰的方法

    不与类或对象绑定,类和对象都可以调用,但是没有自动传值那么一说。就是一个普通函数

    不过由于作用域在类中所以需要使用类或对象类调用

    class OldBoyStudent:
        school = "oldboy"
    
        def __init__(self,name):
            self.name = name
         @staticmethod
        def print_hello():
            print("hello world")
    非绑定方法

    练习:为学生类添加一个save方法 一个get方法

    save是将对象存储到文件中

    get是从文件中获取对象

    import pickle
    
    
    class Student:
        def __init__(self,name):
            self.name = name
    
        def say_hi(self):
            print("name:",self.name)
    
        def save(self):
            with open(self.name,"wb") as f:
                pickle.dump(self,f)
    
        @staticmethod
        def get(name):
            with open(name,"rb") as f:
                obj = pickle.load(f)
                return obj
    
    
    
    # stu = Student("rose")
    # stu.save()
    #
    #
    # stu1 = Student("jack")
    # stu1.save()
    
    # obj = Student.get("rose")
    # print(obj.name)
    #
    # obj = Student.get("jack")
    # print(obj.name)
    
    print(Student.__name__)
    代码


    需求设计王者荣耀中的英雄类,每个英雄对象可以对其他英雄对象使用技能

    具备以下属性

    英雄名称,等级,血量

    和Q_hurt,W_hurt,E_hurt 三个属性,表示各技能的伤害量

    具备以下技能

    Q W E

    三个技能都需要一个敌方英雄作为参数,当敌方血量小于等于0时角色死亡

    import random
    import time
    
    
    class Hero:
    
        def __init__(self,name,level,blood,att,q_hurt,w_hurt,e_hurt):
            # 简便写法
            lcs = locals()
            lcs.pop("self")
            self.__dict__.update(lcs)
    
        def attack(self,enemy):
            enemy.blood -= self.att
            print("%s对%s释放了普通攻击 造成了%s的伤害 敌人剩余血量%s" % (self.name, enemy.name, self.att, enemy.blood))
            if enemy.blood <= 0:
                print("%s被%s使用普通攻击击杀了" % (enemy.name,self.name))
    
    
        def Q(self,enemy):
            enemy.blood -= self.q_hurt
            print("%s对%s释放了Q 造成了%s的伤害 敌人剩余血量%s" % (self.name, enemy.name, self.q_hurt, enemy.blood))
            if enemy.blood <= 0:
                print("%s被%s使用Q技能击杀了" % (enemy.name, self.name))
    
        def W(self,enemy):
            enemy.blood -= self.w_hurt
            print("%s对%s释放了W 造成了%s的伤害 敌人剩余血量%s" % (self.name, enemy.name, self.w_hurt, enemy.blood))
            if enemy.blood <= 0:
                print("%s被%s使用W技能击杀了" % (enemy.name, self.name))
    
        def E(self,enemy):
            enemy.blood -= self.e_hurt
            print("%s对%s释放了E 造成了%s的伤害 敌人剩余血量%s" % (self.name,enemy.name,self.e_hurt,enemy.blood))
    
            if enemy.blood <= 0:
                print("%s被%s使用E技能击杀了" % (enemy.name, self.name))
    
    
    h1 = Hero("亚索",20,2000,100,600,0,1000)
    h2 = Hero("妲己",20,2000,100,600,500,1000)
    h3 = Hero("鲁班",20,1500,700,100,200,300)
    h4 = Hero("蔡文姬",20,2000,10,0,0,10)
    
    
    #
    # h1.attack(h2)
    # h2.Q(h1)
    # h2.E(h1)
    # h2.W(h1)
    
    #从字典中随机拿出一个值
    
    def  random_hero(heros):
        hero_index = random.randint(1, len(heros))
        return heros[hero_index]
    
    
    while True:
        # # 把所有的攻击方法装到字典里  为了随机取出一个
        funcs = {1: Hero.Q, 2: Hero.W, 3: Hero.E, 4: Hero.attack}
        func_index = random.randint(1, 4)
        func = funcs[func_index]
    
    
        # 把所有的英雄方法装到字典里  为了随机取出一个
        heros = {1: h1, 2: h2, 3: h3, 4: h4}
        hero = random_hero(heros)
    
        # 剩余的英雄们
        other_heros = {}
        new_index = 1
        for k, v in heros.items():
            if v != hero:
                other_heros[new_index] = v
                new_index += 1
    
        # 从剩余的英雄中随机挑出一个英雄来挨打
        enemy = random_hero(other_heros)
        # 打他
        func(hero, enemy)
        if enemy.blood <= 0:
            break
        time.sleep(0.5)
    代码

     

     

     

     

  • 相关阅读:
    JavaScript要理解闭包先了解词法作用域
    CSS实现放大镜/狙击镜效果
    如何用js让表格的行也能拖动
    如何用Ajax传一个数组数据
    swf自动播放时如何全屏全部显示
    格式化金额数与自动四舍五入
    HTML标签的使用要注意语义化
    一张图理解"Figure", "Axes", "Axis"
    Python的"random"函数的使用(一)
    "sorted()"中的"Key Functions"
  • 原文地址:https://www.cnblogs.com/komorebi/p/11240702.html
Copyright © 2011-2022 走看看