• 封装


    封装

    一:封装介绍

    封装是面向对象三大特性(封装、继承、多态)中,封装是最核心的一个特性,封装指的就是把数据与功能都整合到一起,针对封装到对象或者类中的属性,我们还可以严格控制对它们的访问,分两步实现:隐藏与开放接口

    二、将封装的属性进行隐藏操作

    1、如何隐藏:在属性名前加__前缀,就会实现一个对外隐藏属性效果

    1.1在类外部无法直接访问双下滑线开头的属性,但知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如Foo._A__N,所以说这种操作并没有严格意义上地限制外部访问,仅仅只是一种语法意义上的变形。

    class Foo:
        __x = 1  # _Foo__x
    
        def __f1(self):  # _Foo__f1
            print('from test')
            
    print(Foo.__dict__)  
    print(Foo._Foo__x)  #通过函数名和属性名拼接成__dict__字典的key,就可以访问了
    print(Foo._Foo__f1)      
    

    1.2 这种属性对外不对内,因为__开头的属性会在检测类体代码语法是统一发生变形__

    class Foo:
        __x=1
        def __f1(self):
            print('from test')
    
        def f2(self):
            print(self.__x)
            print(self.__f1)
    print(Foo.__x)  #type object 'Foo' has no attribute '__x'
    #__开头的属性对外隐藏,在外部直接访问报错,不存在改属性
    print(Foo.__f1)  # type object 'Foo' has no attribute '__f1'
    obj=Foo()
    obj.f2() 
    #1
    <bound method Foo.__f1 of <__main__.Foo object at 0x000001D0B168A8E0>>
    #间接在类体中访问__x和__f1属性,可以访问到
    

    1.3 做的这种变形操作只是在检测类体语法使发生一次,之后新增的__开头的属性都不会发生变形__

    class Foo:
        __x = 1  # _Foo__x = 1
    
        def __f1(self):  # _Foo__f1
            print('from test')
    
        def f2(self):
            print(self.__x) # print(self._Foo__x)
            print(self.__f1) # print(self._Foo__f1)
    
    
    Foo.__y=3  #新增的属性不会变形
    print(Foo.__dict__)
    print(Foo.__y)  #3  可以直接访问到
    

    初始化对象时,可以将对象的属性用___开头的命名方式进行因此,外部不能直接访问

    class Foo:
        __x = 1  # _Foo__x = 1
    
        def __init__(self,name,age):
            self.__name=name
            self.__age=age
    
    obj=Foo('egon',18)
    print(obj.__dict__)
    print(obj.name,obj.age)  #'Foo' object has no attribute 'name'
    
    

    虽然隐藏之后不能直接访问属性,但是可以用函数名和属性名拼接的方式进行访问,这样的话我门为什么要对属性进行隐藏呢?

    2、为何要隐藏?

    2.1 隐藏数据属性"将数据隐藏起来就限制了类外部对数据的直接操作,然后类内应该提供相应的接口来允许类外部间接地操作数据,接口之上可以附加额外的逻辑来对数据的操作进行严格地控制:

    class People:
        def __init__(self,name):
            self.__name=name  #初始化时将名字属性进行隐藏
    
        def get_name(self,password=None):  #类体中提供外部访问的接口
            if password==666:  #接口上附加判断
                print(self.__name)
            else:
                print('没有密码你还行干哈!')
        def set_name(self,val):  #对外提供设置名字的接口
            if type(val) is not str:  #接口上设置判断
                print('必须传入字符串')
                return
            self.__name=val
            
            
    obj = People('egon')
    # print(obj.name) # 无法直接用名字属性
    obj.set_name('EGON')  #传入的是字符串可以设置名字
    obj.set_name(123123123)  #传入的不是字符串,不能设置名字属性
    obj.get_name()  #没有密码你还行干哈!
    obj.get_name(666)  #EGON
    

    隐藏函数/方法属性:目的的是为了隔离复杂度

  • 相关阅读:
    OleDbCommand 的用法
    递归求阶乘
    C#重写窗体的方法
    HDU 5229 ZCC loves strings 博弈
    HDU 5228 ZCC loves straight flush 暴力
    POJ 1330 Nearest Common Ancestors LCA
    HDU 5234 Happy birthday 01背包
    HDU 5233 Gunner II 离散化
    fast-IO
    HDU 5265 pog loves szh II 二分
  • 原文地址:https://www.cnblogs.com/zhangtieshan/p/12664023.html
Copyright © 2020-2023  润新知