• oop 的封装


    封装  

    什么是封装,就是将复杂的丑陋的隐私的细节隐藏起来对外部提供简单的接口

          对外隐藏 内部实现的细节,病体空访问的接口

    为什么要封装

      两个目的

      1,为了保证关键数据的安全性

      2,对外部隐藏实现的细节,隔离复杂度

    什么时候 应该封装 

      当一些数据不希望被外界直接访问直接修改时

      当一些函数不希望被外界使用时

    如何使用 语法

    class Person:
        def __init__(self,name,age,wocaca):
            self.name = name
            self.age = age
            self.__wocaca = wocaca
    p =Person("杨鑫",18,"哦吼")

    这时候通过对象就访问不到这个 wocaca了  只能访问到name age

    被封装的内容的特点:

      1,外部不能直接访问

      2.内部依然可以使用

    权限 

    歇息了封装就可以控制属性的权限

    在python  只有俩中权限

    1 公开的   默认的就是公开的

    2私有的 ,只能由当前类自己使用

    在外界 访问私有的内容

    属性虽然被封转了但是还是需要使用 ,在外界如何访问到封装的属性呢

    通过定义的方法类完成对私有属性的修改 和访问

    class cheng:
    """这是一个秤类 """
    def __init__(self,name,pin_pai,ji_xian): self.name = name self.pin_pai = pin_pai self.__ji_xian = ji_xian def shuchu(self): if self.__ji_xian<=10*20: print("您的体重是",self.__ji_xian) else: print("秤要炸了兄弟") def gaibian(self,xiu_gai): if type(xiu_gai)==int: print("修改成功") self.__ji_xian = xiu_gai else: print("修改数据必须是整形") h = cheng("极限侧重","极限牌",20*10) h.shuchu()
    通过函数内部的值来修改 h.gaibian(
    10*50) h.shuchu()

    这样一来我们可以在外界修改这个关键数据时,做了一些限制

    property 装饰器

    通过方法来修改或者访问属性,本身 没有什么问题 ,但是这给对象对象的使用者带来了很多的麻烦

    使用的时候 必须知道那些是普通属性  那些是私有属性 ,需要使用不同的方式来调用他们

    property装饰器就是就是为了使得调用方式一致

    有三个相关的 装饰器

    1.property  该装饰器用在获取属性的属性方法上

    2.@key.setter  该装饰器用在修改属性的属性方法上

    3.@key.deleter 该装饰器用在删除属性的方法上

    注意:key  是被property装饰的方法的名称,也就是属性的名称

    内部会在创建一个对象,变量名称就是函数的名称

    所以在使用 setter  和deleter时  必须要保证对象的明证调取方法

     

    class A:
        def __init__(self,name,key):
            self.name = name
            self.__key = key
        @property
        def key(self):
            return self.__key
        @key.setter
        def key(self,w_key):
            if w_key <= 100:
                self.__key = w_key
            else:
                print("key 必须小于等于100 ")
        @key.deleter
        def key(self):
            print("不允许删除")
            del self.__key
            #del 是删除变量名  删除 一切变量名 但是加上这个 函数就不允许删除 了
    
    res = A("haha",100)
    print(res.key)
    res.key = 321
    print(res.key)

    python 实现封装的原理

    就在加载的时候,吧 变量前的 双下划线__ 替换成了下划线_类的名字 在加双下划线__

    python 一般不会强制要求程序必须怎么怎么 

    封装:

    对外部隐藏内部的实现细节   并提供接口

    好处:

      1,提高安全性

      2,隔离复杂度

    语法:将要封装的属性或者方法名称前加上双下划线

    访问被隐藏的属性:
      提供用于访问和修改的方法

    使用 proprty装饰器可以将一个方法伪装成一个普通属性,和调用属性方法变得一样

    封装 的实现 原理 ,替换变量名称

    property 可以 用来实现计算属性

    计算属性值得是:属性的值,不能直接获得必须通过计算

    例如:正方形的面积

    作业:


    # 练习: 定义一个类叫做person
    # 包含三个属性 身高 体重 BMI
    # BMI的值需要通过计算得来 公式 体重 / 身高的平方

    class A:
        def __init__(self,shengao,tizhong):
            self.shengao = shengao
            self.tizhong = tizhong
            self.bmi = (self.shengao*self.shengao)/self.tizhong
        @property
        def args(self):
            return self.shengao*self.shengao
    
        @property
        def qwe(self):
            return self.tizhong*self.tizhong
    
    
    
    res = A(177,140)
    
    print(res.bmi)

    接口  了解

      接口是一组功能的集合,但是接口仅包含功能的名字 ,不包含集体实现的代码

    接口本质是一套协议标准,遵循这个标准 的对象就饿能被调用

    接口的目的就是为了提高扩展性:

    例如 电脑提前指定 了 一套usb的接口协议 只要你遵循该协议那么你的设备就可以被电脑使用 否则就用不了

    案例


    ```python
    class USB:
    def open(self):
    pass

    def close(self):
    pass

    def read(self):
    pass

    def write(self):
    pass

    class Mouse(USB):
    def open(self):
    print("鼠标开机.....")

    def close(self):
    print("鼠标关机了...")

    def read(self):
    print("获取了光标位置....")

    def write(self):
    print("鼠标不支持写入....")


    def pc(usb_device):
    usb_device.open()
    usb_device.read()
    usb_device.write()
    usb_device.close()

    m = Mouse()
    # 将鼠标传给电脑
    pc(m)

    class KeyBoard(USB):
    def open(self):
    print("键盘开机.....")

    def close(self):
    print("键盘关机了...")

    def read(self):
    print("获取了按键字符....")

    def write(self):
    print("可以写入灯光颜色....")

    # 来了一个键盘对象
    k = KeyBoard()
    pc(k)
    ```

    在上述案例中,PC的代码一旦完成,后期无论什么样的设备 只要遵循了USB接口协议,都能够被电脑所调用

    接口主要是方便了对象的使用者,降低使用者的 学习难度,只要学习一套使用方法,就可以以不变应万变

    问题:

    如果子类没有按照你的协议来设计,也没办法限制他,将导致代码无法运行

    # 抽象类

    指的是包含抽象方法(没有函数体的方法)的类,

    作用:可以限制子类必须类中定义的抽象方法

    最后:python一般不会限制你必须怎么写,作为一个优秀的程序员,就应该自觉遵守相关协议

    所以有了鸭子类型这么一说:

    如果这个对象长得像鸭子,走路像鸭子,那就他是鸭子

    你只要保证你的类按照相关的协议类编写,也可以达到提高扩展性的目的

    案例:

    ```python

    class Mouse:
    def open(self):
    print("鼠标开机.....")

    def close(self):
    print("鼠标关机了...")

    def read(self):
    print("获取了光标位置....")

    def write(self):
    print("鼠标不支持写入....")

    def pc(usb_device):
    usb_device.open()
    usb_device.read()
    usb_device.write()
    usb_device.close()

    m = Mouse()
    # 将鼠标传给电脑
    pc(m)

    class KeyBoard:
    def open(self):
    print("键盘开机.....")

    def close(self):
    print("键盘关机了...")

    def read(self):
    print("获取了按键字符....")

    def write(self):
    print("可以写入灯光颜色....")


    # 来了一个键盘对象
    k = KeyBoard()
    pc(k)

    class UDisk:
    def open(self):
    print("U盘启动了...")

    def close(self):
    print("U盘关闭了...")

    def read(self):
    print("读出数据")

    def write(self):
    print("写入数据")

    u = UDisk()
    pc(u)
    ```

    接口是一套协议规范,明确子类们应该具备哪些功能

    抽象类是用于强制要求子类必须按照协议中规定的来实现

    然而,python不推崇限制你的语法, 我们可以设计成鸭子类型,既让多个不同类对象具备相同的属性和方法

    对于使用者而言,就可以以不变应万变,轻松的使用各种对象

  • 相关阅读:
    【Codeforce 487E】【UOJ#30】—Tourists(圆方树+树链剖分)
    【省选模拟】—River(贪心)
    【BZOJ4012】【HNOI2015】—开店(动态点分治)
    【BZOJ4543】【POI2014】Hotel加强版(长链剖分)
    【BZOJ3809】—GTY的二逼妹子序列(莫队+权值分块)
    【BZOJ2878】【NOI2012】—迷失游乐园(基环树期望dp)
    【2019省选模拟】—树(并查集+容斥)
    【BZOJ2120】—数颜色(带修莫队)
    【BZOJ3597】【SCOI2014】—方伯伯运椰子(分数规划)
    【BZOJ3598】【SCOI2014】方伯伯的商场之旅(数位dp)
  • 原文地址:https://www.cnblogs.com/yangxinpython/p/11264700.html
Copyright © 2020-2023  润新知