zoukankan      html  css  js  c++  java
  • Python-27_面向对象

    # 三大编程范式:
    # 1、面向过程编程
    # 2、函数式编程
    # 3、面向对象编程
    # 特点:
    # 面向过程---复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现)
    #            面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式
    # 面向对象---解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
    # 对象是具体的存在,而类仅仅只是一个概念,并不真实存在!!
    # 在程序中:务必保证先定义类,后产生对象!!
    #
    # 如果我们把数据和动作内嵌到一个结构(函数或类)中,那么我们就有了一个“对象系统”(对象就是数据与函数整合到一起的产物)
    #
    #
    # ##### 面向对象设计:将一类具体事物的数据和动作整合到一起,即为面向对象设计。
    # ##### 面向对象编程:用定义类+实例/对象的方法去实现面向设计。
    #
    # 类------把一类事物的相同特征和动作整合到一起就是类,类是一个抽象的概念;
    # 对象------基于类而创建的一个具体的事物(一个具体的存在),也是特征和动作整合到一起;
    # 实例化------由类生产对象的过程叫实例化;
    
    # 例子:----初接触
    # def people(name,age,gender):            # 这是一个类,统称为:人
    #     def eat(x):
    #         print("%s正在吃饭饭,请不要打扰"%x["name"])
    #     def wushu(x):
    #         print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(x["name"],x["name"],x["gender"],x["age"]))
    #     def feature(name,age,gender):       # 对对象进行初始化
    #         dic={"name":name,"age":age,"gender":gender,"eat":eat,"wushu":wushu}
    #         return dic
    #     return feature(name,age,gender)
    # people01=people("newmet1",15,"男")     # 生成一个人(对象),叫(newmet1),这个对象是符合“人”这一类中特征与动作的一个具体的存在
    # print(people01)
    # people01["wushu"](people01)
    # people01["eat"](people01)
    
    # 例子:----面向对象编程:
    class people:                           # 这是一个类,统称为:人
    
        def eat(self):
            print("%s正在吃饭饭,请不要打扰"%self.name)
        def wushu(self):
            print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(self.name,self.name,self.gender,self.age))
        def __init__(self,name,age,gender):       # 初始化函数
            self.name=name
            self.age=age
            self.gender=gender
    people01=people("newmet1",15,"")     # 生成一个人(对象),叫(newmet1),这个对象是符合“人”这一类中特征与动作的一个具体的存在
    print(people01.__dict__)        # {'name': 'newmet1', 'age': 15, 'gender': '男'}
    people01.eat()                  # newmet1正在吃饭饭,请不要打扰
    people01.wushu()                # newmet1正在准备开始练功:(欲练此功,必先自宫!)哎!newmet1 男 年仅15岁
    
    
    # 用面向对象语言写程序(是利用class等方法写),和一个程序的设计是面向对象的,完全是两回事!!
    01-面向对象设计
    #--------------  类  --------------#
    # class School:
    #     # 这个类具体是干什么用的 #
    #     pass
    # v=School()        # 类的实例化(类名+())
    # print(v)          # <__main__.School object at 0x00000000020A6400>
    
    # 一、经典类、新式类
    # python2 中,类分:经典类、新式类;
    # python3 中,类只有新式类(就是python2中的经典类)
    # 经典类:
    # class 类名:
    #     pass
    
    # 新式类:
    # class 类名(父类):      # 这个类继承自--父类
    #     pass
    
    
    # 二、类:属性:
    #           1、数据属性
    #           2、函数属性
    class friend:
        "这是一个朋友类"
        v=111
        def s():
            print("222")
    
    print(dir(friend))          # 查出的是一个名字列表
    print(friend.__dict__)      # 查看属性字典(内存地址)
    print(friend.v)             # 111
    friend.s()                  # 222
    print(friend.__dict__["v"]) # 111
    friend.__dict__["s"]()      # 222
    
    print(friend.__name__)      # friend
    print(friend.__doc__)       # 这是一个朋友类
    print(friend.__base__)      # <class 'object'>
    print(friend.__bases__)     # (<class 'object'>,)
    print(friend.__module__)    #  __main__
    print(friend.__class__)     # <class 'type'>
    
    """
    #python为类内置的特殊属性
    
    类名.__name__     # 类的名字(字符串)
    类名.__doc__      # 类的文档字符串
    类名.__base__     # 类的第一个父类(在讲继承时会讲)
    类名.__bases__    # 类所有父类构成的元组(在讲继承时会讲)
    类名.__dict__     # 类的属性字典
    类名.__module__   # 类定义所在的模块
    类名.__class__    # 实例对应的类(仅新式类中)
    
    """
    02-类
    class people:                           # 这是一个类,统称为:人
    
        def eat(self):
            print("%s正在吃饭饭,请不要打扰"%self.name)
        def wushu(self):
            print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(self.name,self.name,self.gender,self.age))
        def __init__(self,name,age,gender):       # 初始化函数
            self.name=name
            self.age=age
            self.gender=gender
    v1=people("newmet1",15,"")     # 实例化的过程          self --- v1  其就是实例化的结果
    print(v1.__dict__)        # {'name': 'newmet1', 'age': 15, 'gender': '男'}
    v1.eat()      # 自动给eat传了一个self参数     # newmet1正在吃饭饭,请不要打扰
    v1.wushu()    # 自动给wushu传了一个self参数   # newmet1正在准备开始练功:(欲练此功,必先自宫!)哎!newmet1 男 年仅15岁
    
    print(v1.__dict__["name"])      # newmet1
    print(v1.name)                  # newmet1
    03-对象
    class friend:
        def __init__(self,name):
            print("名字:%s"%name)
        name="newmet"
        def play_ball(self):
            print("正在打球")
    
    # 增加
    # friend.age=18
    #
    # def eat():
    #     print("函数属性增加")
    # friend.eat=eat
    # print(friend.__dict__)
    # friend.eat()
    
    # 删除
    # del friend.name
    # print(friend.__dict__)
    
    # 修改
    friend.name="2222"
    
    def eat():
        print("函数属性修改")
    friend.play_ball=eat
    print(friend.name)
    print(friend.play_ball())
    04-类属性增删修查
    class friend:
        def __init__(self,name):
            self.name=name
        age=18
        def play_ball(self):
            print("正在打球")
    v=friend("newmet")
    print(v.__dict__)
    
    # 查看
    # print(v.age)
    # print(v.play_ball)
    
    # 增加  (实例属性只能增加数据属性)
    v.gender=""
    print(v.__dict__)
    print(v.gender)
    
    # 修改
    v.name="121"
    print(v.__dict__)
    print(v.name)
    05-实例属性增删修查
    country="中国-----------"
    class Chinese:
        country="中国"
        def __init__(self,name):
            self.name=name
            print(">>>",country)                        #  没.(没实例化)  不在类中找,与实例无关
        def play_ball(self,ball):
            print("%s 正在玩 %s" %(self.name,ball))
    
    print(Chinese.__dict__)
    print(Chinese.country)          # 中国
    p=Chinese("new")               # >>> 中国-----------  没.(没实例化)  不在类中找,与实例无关
    print("实例化",p.country)      # 实例化 中国
    06-对象与实例属性
    #--------------------------------- 静态属性 --------------------------------#
    # class Room:
    #     def __init__(self,name,owner,length,width,height):
    #         self.name=name
    #         self.owner=owner
    #         self.length=length
    #         self.width=width
    #         self.heigth=height
    #     @property               # 封装逻辑。 隐藏背后的逻辑,调用方式表面上和调用数据属性一样。
    #     def cal_area(self):
    #         # print("%s住在叫%s的%s平米的房子中"%(self.owner,self.name,(self.length*self.width)))
    #         return self.length*self.width
    #
    # v1=Room("1号房间","new1",50,50,4)
    # v2=Room("2号房间","new2",30,30,4)
    # # v1.cal_area()       # new1住在叫1号房间的2500平米的房子中
    # # v2.cal_area()       # new2住在叫2号房间的900平米的房子中
    # # v1.cal_area           # new1住在叫1号房间的2500平米的房子中(类中增加 @property 后,不需要加括号)
    # # v2.cal_area           # new2住在叫2号房间的900平米的房子中 (类中增加 @property 后,不需要加括号)
    #
    # print(v1.cal_area)      # 2500     @property隐藏背后的逻辑,调用方式表面上和调用数据属性一样。
    # print(v2.cal_area)      # 900
    # print(v1.name)          # 1号房间      调用数据属性
    # print(v2.name)          # 2号房间
    
    
    
    #--------------------------------- 类方法 --------------------------------#
    # class Room:
    #     food=1
    #     def __init__(self,name,owner,length,width,height):
    #         self.name=name
    #         self.owner=owner
    #         self.length=length
    #         self.width=width
    #         self.heigth=height
    #     @classmethod               # 将下列方法变成可以被类调用的方法
    #     def cal_area(cls):
    #         print(cls)                          # <class '__main__.Room'>
    #         print("%s newmet"%cls.food)       # 1 newmet
    #
    # # v1=Room("1号房间","new1",50,50,4)
    # # v2=Room("2号房间","new2",30,30,4)
    # Room.cal_area()
    # # 类调用自己的属性方法的时候 ,与实例没有关系
    
    
    #--------------------------------- 静态方法 --------------------------------#
    
    class Room:
        food=1
        def __init__(self,name,owner,length,width,height):
            self.name=name
            self.owner=owner
            self.length=length
            self.width=width
            self.heigth=height
        @property               # 封装逻辑。 隐藏背后的逻辑,调用方式表面上和调用数据属性一样。
        def cal_area(self):
            # print("%s住在叫%s的%s平米的房子中"%(self.owner,self.name,(self.length*self.width)))
            return self.length*self.width
    
        @classmethod               # 将下列方法变成可以被类调用的方法
        def cal_area1(cls):
            print(cls)                          # <class '__main__.Room'>
            print("%s newmet"%cls.food)       # 1 newmet
    
        @staticmethod
        def bath(x):
            print("%s 正在沐浴" %x)
    
    Room.cal_area1()
    
    Room.bath("new")
    v1=Room("1号房间","new1",50,50,4)
    v1.bath("met")
    
    # @property      ----  和实例绑定,与类无关
    # @classmethod   ----  和类绑定,与实例无关
    # @staticmethod  ----  和类和实例均不绑定(类的工具包)
    # @staticmethod -- 静态方法只是名义上的归属类管理,不能使用类变量和实例变量,只是类的工具包
    
    #--------------------------------- 总结 --------------------------------#
    
    # @property      ----  能访问类的数据、函数属性以及实例的属性
    # @classmethod   ----  只能访问类的属性
    # @staticmethod  ----  不能访问类、实例属性
    07-静态属性_方法
    #--------------------- 定义锐雯类:---------------------
    class Raven:
        camp='Noxus'
        def __init__(self,nickname,
                     aggressivity=54,
                     life_value=414,
                     money=1001,
                     armor=3):
            self.nickname=nickname
            self.aggressivity=aggressivity
            self.life_value=life_value
            self.money=money
            self.armor=armor
        def attack(self,enemy):
            damage_value=self.aggressivity-enemy.armor
            enemy.life_value-=damage_value
    
    #--------------------- 定义盖伦类:---------------------
    class Galen:
        camp='Demacia'
        def __init__(self,nickname,
                     aggressivity=58,
                     life_value=455,
                     money=100,
                     armor=10):
            self.nickname=nickname
            self.aggressivity=aggressivity
            self.life_value=life_value
            self.money=money
            self.armor=armor
        def attack(self,enemy):
            damage_value=self.aggressivity-enemy.armor
            enemy.life_value-=damage_value
    
    #--------------------- 定义装备:---------------------
    class BlackCleaver:
        def __init__(self,price=475,aggrev=9,life_value=100):
            self.price=price
            self.aggrev=aggrev
            self.life_value=life_value
        def update(self,obj):
            obj.money-=self.price #减钱
            obj.aggressivity+=self.aggrev #加攻击
            obj.life_value+=self.life_value #加生命值
        def fire(self,obj): #这是该装备的主动技能,喷火,烧死对方
            obj.life_value-=1000 #假设火烧的攻击力是1000
    
    #--------------------- 测试交互:---------------------
    r1=Raven('草丛伦')
    g1=Galen('盖伦')
    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就死了
    08-基于面向对象设计的一个对战游戏 
    # 获取指定位置上的·某个方向·指定数量的元素。
    # 变化特征              "20"    右侧  0  1     (索引列r、行c、累加)
    # 变化特征              "31"    上方 -1  0     (索引列r、行c、累加)
    # 变化特征              "24"    左侧 0  -1     (索引列r、行c、累加)
    # 变化特征              "03"    下方 1   0     (索引列r、行c、累加)
    
    #
    # def get_elements(list_target,r_index,c_index,r_dir,c_dir,count):
    #     """
    #     获取指定位置上的·某个方向·指定数量的元素。
    #     :param list_target: list
    #     :param r_index:列索引
    #     :param c_index:行索引
    #     :param r_dir:方向
    #     :param c_dir:方向
    #     :param count:次数--数量
    #     :return:
    #     """
    #     result = []
    #     for item in range(count):
    #         r_index += r_dir
    #         c_index += c_dir
    #         result.append(list_target[r_index][c_index])
    #     return result
    #
    #
    # list01=[
    #     ["00","01","02","03","04"],
    #     ["10","11","12","13","14"],
    #     ["20","21","22","23","24"],
    #     ["30","31","32","33","34"],
    #     ["40","41","42","43","44"]
    # ]
    #
    #
    # print(get_elements(list01,2,4,0,-1,3))
    
    
    """
    该方式是:面向过程
    
    缺点:
        1.代码可读性差
        2.每次调用方法,都需要思考方向(索引变化)的特征
        
    
        
    """
    
    
    # 解决方法:
    #       1.使用一个类,包装两个数据(行/列)
    #       2.利用静态方法
    class Vector2:
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
        # def right(self):
        #     return Vector2(0,1)
    
        # 静态方法:不依赖于对象、类
        @staticmethod
        def right():
            return Vector2(0, 1)
    
        @staticmethod
        def up():
            return Vector2(-1, 0)
    
        @staticmethod
        def down():
            return Vector2(1, 0)
    
        @staticmethod
        def left():
            return Vector2(0, -1)
    
    
    def get_elements(list_target, vect_pos, vect_dir, count):
        """
        获取指定位置上的·某个方向·指定数量的元素。
        :param list_target: list
        :param r_index:列索引
        :param c_index:行索引
        :param r_dir:方向
        :param c_dir:方向
        :param count:次数--数量
        :return:
        """
        result = []
        for item in range(count):
            vect_pos.x += vect_dir.x
            vect_pos.y += vect_dir.y
            result.append(list_target[vect_pos.x][vect_pos.y])
        return result
    
    
    list01 = [
        ["00", "01", "02", "03", "04"],
        ["10", "11", "12", "13", "14"],
        ["20", "21", "22", "23", "24"],
        ["30", "31", "32", "33", "34"],
        ["40", "41", "42", "43", "44"]
    ]
    
    print(get_elements(list01, Vector2(2, 0), Vector2.right(), 3))
    09-静态方法_精华案例
  • 相关阅读:
    浏览器的reflow和repaint
    javascript正则表达式中参数g的作用
    InkCanvas 自由虚线笔画
    WPF 圆轮菜单的实现
    WPF实现化学式上下标
    install and use zookeeper C client API
    install and use boost::thread
    explicit instantiations in template class/function
    The science of programming
    how does vector work?
  • 原文地址:https://www.cnblogs.com/newmet/p/10511331.html
Copyright © 2011-2022 走看看