zoukankan      html  css  js  c++  java
  • day28---面向对象之封装

    一、封装的引入


    1、封装< -- >整合

    # 封装是面向对象三大特性最核心的一个特性
    封装指的就是把数据与功能都整合到一起

    除此之外,针对封装到对象或者类中的属性,我们还可以严格控制对它们的访问,分两步实现:隐藏与开放接口

    2、将封装的属性进行隐藏

    Python的Class机制采用双下划线开头的方式将属性隐藏起来(设置成私有的),但其实这仅仅只是一种变形操作,类中所有双下滑线开头的属性都会在类定义阶段、检测语法时自动
    变成“_类名__属性名”的形式:
    class Foo:
        __N=0 # 变形为_Foo__N
    
        def __init__(self): # 定义函数时,会检测函数语法,所以__开头的属性也会变形
            self.__x=10 # 变形为self._Foo__x
    
        def __f1(self): # 变形为_Foo__f1
            print('__f1 run')
    
        def f2(self):  # 定义函数时,会检测函数语法,所以__开头的属性也会变形
            self.__f1() #变形为self._Foo__f1()
    
    print(Foo.__N) # 报错AttributeError:类Foo没有属性__N
    
    obj = Foo()
    print(obbj.__x) # 报错AttributeError:对象obj没有属性__x

    总结:

    #1、在类外部无法直接访问双下滑线开头的属性,但知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如Foo._A__N,所以说这种操作并没有严格意义上地
    限制外部访问,仅仅只是一种语法意义上的变形。
    #2、这种隐藏对外不对内,因为__开头的属性会在检查类体代码语法时统一发生变形 #3、这种变形操作只在检查类体语法的时候发生一次,之后定义的__开头的属性都不会变形

    二、开放接口


    定义属性的目的是为了使用,所以隐藏不是根本目的

    1、隐藏数据属性

    将数据隐藏起来就限制了类外部对数据的直接操作,然后类内应该提供相应的接口来允许类外部间接地操作数据,接口之上可以附加额外的逻辑来对数据的操作进行严格地控制
    >>> class Teacher:
    ...     def __init__(self,name,age): #将名字和年纪都隐藏起来
    ...         self.__name=name
    ...         self.__age=age
    ...     def tell_info(self): #对外提供访问老师信息的接口
    ...         print('姓名:%s,年龄:%s' %(self.__name,self.__age))
    ...     def set_info(self,name,age): #对外提供设置老师信息的接口,并附加类型检查的逻辑
    ...         if not isinstance(name,str):
    ...             raise TypeError('姓名必须是字符串类型')
    ...         if not isinstance(age,int):
    ...             raise TypeError('年龄必须是整型')
    ...         self.__name=name
    ...         self.__age=age

    2、隐藏函数属性

    目的的是为了隔离复杂度,例如ATM程序的取款功能,该功能有很多其他功能组成,比如插卡、身份认证、输入金额、打印小票、取钱等,而对使用者来说,只需要开发取款这个功能
    接口即可,其余功能我们都可以隐藏起来
    >>> class ATM:
    ...     def __card(self): #插卡
    ...         print('插卡')
    ...     def __auth(self): #身份认证
    ...         print('用户认证')
    ...     def __input(self): #输入金额
    ...         print('输入取款金额')
    ...     def __print_bill(self): #打印小票
    ...         print('打印账单')
    ...     def __take_money(self): #取钱
    ...         print('取款')
    ...     def withdraw(self): #取款功能
    ...         self.__card()
    ...         self.__auth()
    ...         self.__input()
    ...         self.__print_bill()
    ...         self.__take_money()
    ...
    >>> obj=ATM()
    >>> obj.withdraw()

    三、property装饰器


    Python中专门提供了一个装饰器property,可以将类中的函数“伪装成”对象的数据属性,对象在访问该特殊属性时会触发功能的执行,然后将返回值作为本次访问的结果。

    我们以BMI为例子

    #BMI指数是用来衡量一个人的体重与身高对健康影响的一个指标,计算公式为:
    
    体质指数(BMI)=体重(kg)÷身高^2(m)
    EX:70kg÷(1.75×1.75)=22.86
    #!/usr/bin/env python
    
    class People:
        def __init__(self, name, weight, height):
            self.name = name
            self.weight = weight
            self.height = height
    
        @property
        def get_bmi(self):
            return self.weight / (self.height ** 2)
    
    
    people_obj1 = People('姜春', 60, 1.75)
    print(people_obj1.get_bmi)

    使用property可以保证属性访问的一致性。此外,property还提供了设置,删除的属性功能,如下

    class People:
        def __init__(self, name):
            self.__NAME = name
    
        @property
        def show_name(self):
            return self.__NAME   #将属性隐藏起来
    
        @show_name.setter
        def show_name(self,value):
            if not isinstance(value,str):   #在设定值之前进行类型检查
                raise TypeError('{} must be str'.format(value))
            self.__NAME = value   #通过类型检查后,将值value存放到真实的位置self.__NAME
    
        @show_name.deleter
        def show_name(self):
            raise PermissionError('can not delete')
    
    p = People('姜春')
    print(p.show_name)      #姜春
    p.show_name = '王鹏'
    print(p.show_name)      #王鹏
    p.show_name = 1024
    print(p.show_name)      #TypeError: 1024 must be str
    del p.show_name          #PermissionError: can not delete
  • 相关阅读:
    PCB 规则引擎之脚本语言JavaScript应用评测
    PCB 挺有意思的基数排序----C#代码实现
    PCB NOSQL MongoDb MI流程指示数据存储结构
    PCB javascript解析Gerber274X格式实现方法
    PCB javascript解析钻孔(Excellon)格式实现方法
    PCB 围绕CAM自动化,打造PCB规则引擎
    PCB Genesis拼SET画工艺边 实现方法(一)
    约瑟夫环的三种解法
    Microsoft edge真香!
    商城规格参数
  • 原文地址:https://www.cnblogs.com/surpass123/p/12659773.html
Copyright © 2011-2022 走看看