7.26面向对象之封装(接口与抽象)

一。封装。

  封装就是将丑陋复杂的隐式的细节隐藏到内部,对外提供简单的使用接口。

  对外隐藏内部实现细节,并提供访问的接口。对内使用self操作。

二。为什么要封装?

  对于一个计算机来说,不可能不使用机箱就将处理器,内存,硬盘等东西暴露在外面交给用户,所以对于程序来说也是一样的,目的有2:

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

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

  电脑的cpu老是露在外面也不是很安全。

三。封装的使用环境

  当有些数据不希望外界可以直接对其修改的时候。

  当有些函数不希望给外界使用时。

  这些数据通常都是程序的核心,不提倡改动的数据。

四。封装的语法

class A:
    def __init__(self,name,key):
        self.name=name
        self.__key=key

a=A('lma',666)
a.key=9
print(a.key)
print(a.__dict__)
#9
#{'name': 'lma', '_A__key': 666, 'key': 9}

  当在初始化一个类时,在接受参数前加上双下划线,再使用a.key访问数据时时不存在的,其实就类初始化的原理就可以发现在初始化时根本就没有key这个关键字,有的只是__key,所以不会访问,不过在访问_类名__变量名时也可以访问到该封装变量。

print(a._A__key)
#666

  所以封装的根本原理就是将原来的替换成了上面的关键变量。

  而强行在原对象里添加该参数得到的只是一个新 的参数,使用__dict__就可以看出来。

五。权限

  既然封装了,那就代表外界不能随便访问了所以需要对属性设置权限时就可以使用封装

  1。公开的属性,不需要进行封装

  2.私有的,只能由当前类自己使用,需要封装。

六。访问封装属性

  封装是使得属性不能对外直接访问,但不应该是完全不能访问,否则封装的数据就等于没有这个数据,除了上述使用类名加属性 的方法来访问之外,还可以使用定义函数的方法对私有类进行访问和修改。

class Downer:
    def __init__(self,name,url,All):
        self.name=name
        self.url=url
        self.__All=All

    def get_all(self):
        return self.__All

    def set_all(self,all):
        if type(all)==int:
            self.__All=all
        else:
            print('not int')

dow=Downer('啦啦啦','www.baidu.com',512)
print(dow.get_all())
dow.set_all(213)
print(dow.get_all())
#512
#213

  这样通过get和set可以对内部的封装属性进行操作。

七。property装饰器

  使用方法对属性进行修改,虽然可行,但是对于使用这个类的人来说,必须分清哪个是普通属性,哪个是是私有属性,这使用起来 非常麻烦,而使用property装饰器就可以使得和原来普通的方法调用一致。

  装饰器一共有三个,分别有不同的作用。

  1.@property 可以使用在获取属性上。

  2.@属性名.setter 可以使用在修改属性上

  3.@属性名.deleter 可以使用在删除该属性上  

  用法如下:

class New:
    def __init__(self,name,data):
        self.name=name
        self.__data=data

    @property
    def data(self):
        return self.__data

    @data.setter
    def data(self,dat):
        self.__data=dat

    @data.deleter
    def data(self):
        del self.data

  经过装饰器装饰后的方法就可以将其和原来的属性一样使用,只有当property装饰了一个方法之后其他的装饰器才有用,装饰的方法最好和封装的属性名一样。

  那么问题来了,装饰后的封装属性和原来的普通属性不是一样使用吗,为什么还要大费周章的封装呢?

  其实在上述代码中可以看到,在使用装饰器时可以对函数进行操作,比如不写返回值就可以不返回值,或者提示该属性不能被访问,在修改时可以提示该值不能被修改,删除也是一样。

  总结:装饰器封装可以将封装属性当成普通属性使用,对其装饰的函数进行限制可以获得不同的效果。

  其好处有:

    1.提高安全性

    2.隔离复杂度

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

  访问被隐藏的属性:

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

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

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

八。接口interface

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

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

  以电脑为例,电脑不分usb是键盘接口还是鼠标接口,只要符合usb的接口设备都可以插上使用,所以为这个现象建模:

class Usb:
    def start(self):
        pass

    def close(self):
        pass

    def work(self):
        pass

def pc(oop):
    oop.start()
    oop.work()
    oop.close()

class mouse(Usb):
    def start(self):
        print('鼠标启动')

    def work(self):
        print('鼠标工作')

    def close(self):
        print('鼠标关闭')


class key(Usb):
    def start(self):
        print('键盘启动')

    def work(self):
        print('键盘工作')

    def close(self):
        print('键盘关闭')

newmouse=mouse()
newkey=key()
pc(newmouse)
pc(newkey)
#鼠标启动
#鼠标工作
#鼠标关闭
#键盘启动
#键盘工作
#键盘关闭

  usb就相当于一个接口,限制了帮助pc工作的工具。而即使没有这个接口,如果那个工具也有这些功能亦可以工作。所以对于其他语言来说(如java),interface是一个关键字,是定义接口类不得不写的东西,而对于python来数,interface只是一个概念。

九。抽象类

import abc

class Aclass(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def run(self):
        pass

class B(Aclass):
    pass

c=B()

  如上定义了一个抽象类,其使用模块abc,在类中使用装饰器对其方法进行抽象

  装饰过的方法在子类继承它时,必须重写该类,否则就会实例化失败。这种限制是强制性的,因为会把程序卡在创建对象的时候。

十。鸭子类型

  当一个东西,长得像鸭子,叫声像鸭子,走路像鸭子,那它就是鸭子,python程序也是一样的,python不喜欢太多限制程序的规定,所以在编写时都是基于大家一起遵守的规定。

 

posted on 2019-07-26 20:55  一只萌萌哒的提莫  阅读(146)  评论(0编辑  收藏  举报