• 对象的封装与接口


    一.对象的封装

    什么是封装:对外隐藏内部实现细节,并提供访问的接口

    封装的目的:

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

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

    什么时候应该封装:

    当有一些数据不希望外界可以直接修改时

    ​ 当有一些函数不希望给外界使用时,

     如何封装:

    class Person:
            def __init__(self,id_number,name,age)
            self.__id_number = id_number
            # 比如这里是比较重要的身份证号码,不能随便调用
            # 给属性或者方法前面加上 __   
            def show_id(self):
               print(self.__id_number)
    
            def __say_hi(self):
               print(f"hi, 我是{self.name}")
    
    
    p = Person('35676549809711', 'bitten', 29)
    p.id_number = '3756789'  # 这里其实是给对象加了个属性 id_number(对象属性的增删改查)
    print(p.id_number)
    # 3756789
    p.show_id()
    # 35676549809711  # 并没有受到影响
    # p.__id_number  # 报错,pycharm没有提示也找不到,AttributeError: 'Person' object has no attribute '__id_number'
    # p.__say_hi  # 报错,AttributeError: 'Person' object has no attribute '__say_hi'双下划线,外界就访问不到了
            self.name = name
            self.age = age
       
    p = Person("35676549809711","bitten",29)
    
    p.id_number = "222"
    View Code

    被封装内容的特点:

    1.外界不能直接访问

    ​ 2.内部依然可以使用

    封装可以控制属性的权限

    python的两种权限:

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

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

    外界访问私有内容:通过定义方法类可以完成在外部对私有属性的修改和访问

    """
    这是一个下载器类,需要提供一个缓存大小这样的属性
    缓存大小不能超过内存限制
    
    """
    class Downloader:
        def __init__(self,filename,url,buffer_size):
            self.filename = filename
            self.url = url
            self.__buffer_size= buffer_size
    
        def start_download(self):
            if self.__buffer_size <= 1024*1024:
                print("开始下载....")
                print("当前缓冲器大小",self.__buffer_size)
            else:
                print("内存炸了! ")
    
    
        def set_buffer_size(self,size):
            #可以在方法中添加额外的逻辑
            if not type(size) == int:
                print("大哥 缓冲器必须是整型")
            else:
                print("缓冲区大小修改成功!")
                self.__buffer_size = size
    
        def get_buffer_size(self):
            return self.__buffer_size
    
    d = Downloader("葫芦娃","http://www.baicu.com",1024*1024)
    
    
    # 通过函数取修改内部封装的属性
    d.set_buffer_size(1024*512)
    
    # 通过函数访问内部封装的属性
    print(d.get_buffer_size())
    
    d.start_download()
    View Code

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

    访问被隐藏的属性:

    ​提供用于访问和修改的方法

    使用property装饰器可以将一个方法伪装成普通顺属性,让属性之间调用方法一致

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

    二.装饰器

    property装饰就是为了使普通属性和私有属性得调用方式一致

    1.property 该装器用在获取属性的方法上
    2.@key.setter 该装饰器用在修改属性的方法上
    3.@key.deleter 该装饰器用在删除属性的方法上

    注意:key是被property装饰的方法的名称 也就是属性的名称
    内部会创建一个对象 变量名称就是函数名称
    所以在使用setter和deleter时 必须保证使用对象的名称取调用方法
    所以是 key.setter
    ```

    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,new_key):
            if new_key <= 100:
                self.__key = new_key
            else:
                print("key 必须小于等于100")
    
        
        @key.deleter
        def key(self):
            print("不允许删除该属性")
            del self.__key
            
    a = A("jack",123)
    print(a.key)
    a.key = 321
    print(a.key)
    View Code

    python实现封装的原理

    就是在加载类的时候,把_ _替换成了 _类名_ _

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

    property 实现计算属性

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

    例如:正方形求面积

    class Square:  # 正方形
    
        def __init__(self, width):
            self.width = width
            self.area = self.width * self.width
    
    
    s = Square(10)
    print(s.area)
    # 100
    
    s.width = 20
    print(s.area)  # 后续更改了width,它的值就不对了
    # 100
    
    
    class Square2:  # 正方形
    
        def __init__(self, width):
            self.width = width
            # self.area = self.width * self.width  # 下面定义的时候要把这里去掉
    
        @property  # 只要 . 这个属性, 就会自动触发这个函数
        def area(self):
            return self.width * self.width
    
    
    s2 = Square2(10)
    print(s2.area)
    # 100
    
    s2.width = 20
    print(s2.area)
    # 400
    View Code

    三.接口

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

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

    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)
    View Code

    接口目的:提高扩展性:

    四.抽象类

    抽象类abstract class:类中包含 没有函数体的方法

    import abc
    
    class AClass(metaclass=abc.ABCMeta):
    
        @abc.abstractmethod
        def run(self):
            pass
        @abc.abstractmethod
        def run1(self):
            pass
    
    
    class B(AClass):
    
        def run(self):
            print("runrunrurn...")
    
    b = B()
    View Code

    抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化,且子类必须实现抽象方法

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

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

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

    然而,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)
    View Code
  • 相关阅读:
    MoSQL
    Open Search Server 1.4 Beta3 发布
    NxWidgets 1.5 发布,NuttX的GUI开发包
    segatex 7.900 发布,SELinux 策略编辑器
    MySQL Connector/ODBC 5.2.4 发布
    Phing 2.5 发布,PHP 项目构建工具
    SwingX 1.6.5 发布,GUI 工具包
    XWiki 4.4.1 发布,Java 的 Wiki 引擎
    流言终结者——C语言内存管理
    Hudson 3.0 正式版发布,持续集成引擎
  • 原文地址:https://www.cnblogs.com/Cpsyche/p/11261140.html
Copyright © 2020-2023  润新知