zoukankan      html  css  js  c++  java
  • (7)类的封装--反射方法

    1. 什么是封装
    装:将属性装到一个容器里,该容器可以是类也可以是对象

    封:指的是将装到容器里的对象给隐藏起来,该隐藏是对外不对内的

    2. 为何要封装

    隐藏数据属性的目的

    把数据属性隐藏起来,是为了外使用者不能直接操作属性,而是通过类内部开辟的接口来间接地操作属性 我们可以在接口之上附加任意的控制逻辑,从而严格控制使用者对属性的操作

    隐藏函数属性的目的:

    3. 如何封装
    在函数名或属性前加 __或者_

    PS:反射取__的函数或者属性时必须在传入的字符串名前面加‘_类名’,否则取不到函数,包括hasattr判断也同理

    PS:如果是_的函数则可以直接用反射系列的方法取值

    例:

    class FTPHandler():
    def handle(self):
    print('1')
    if hasattr(self,"_FTPHandler__get"): # hasattr判断如果有这个函数名,调用私有地址的方式是_父类名+私有地址的函数名将名字拼成私有地址的格式
    print('yes')
    else:
    print('输入错误')

    def __get(self):
    '''收取文件的函数'''
    print('123')

    ftp = FTPHandler()
    ftp.handle()

     

    封装实例

    class Foo:
    __x=1 #这里就是封装
    def __init__(self,name,age):
    self.__name=name #这里是封装
    self.__age=age #这里是封装

    def tell_info(self): #这里定义一个函数用来查看类体内的封装
    print(self.__name,self.__age,self.__x,Foo.__x)

    print(Foo.__x) #这时候已经访问不到x这个值,外部访问已经查找不到
    obj=Foo('egon',18)
    print(obj.__name,obj.__age) #这里对象也访问不到,外部访问已经查找不到
    print(obj.__dict__)
    PS:原理就是类的静态函数、类函数、普通函数、全局变量以及一些内置的属性都是放在类__dict__里的,生成一个key:value的字典,然后在代码执行时候就会以key查找
    但凡__开头的属性,在类定义的时候,就会在字典里加上__开头存入
    obj.tell_info() #类内的函数可以访问到
    # print(Foo._Foo__x)#通过这样的方式就可以访问到,所以不是绝对隐藏
    # print(obj._Foo__name)

    注意:
    1. __开头属性会在类定义阶段检测语法时发生变形,变形规则: _类名__属性名
    2. 类定义阶段之后新增的__开头的属性不会变形
    3. 在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为隐藏的

    class Foo:
    __x = 1 #这里在定义的时候就发生了变形

    def __init__(self, name, age):
    self.__name = name #这里在定义的时候就发生了变形
    self.__age = age #这里在定义的时候就发生了变形

    def tell_info(self):
    print(self.__name) #这里在定义的时候就发生了变形

    obj=Foo('egon',18)

    obj.__yyy=111 #类定义之后新增不会发生变形
    print(obj.__dict__) #查看下有没有变形
    print(obj.__yyy) #这里可以直接访问到



    class Foo:
    def __f1(self): #在类定义阶段变形成Foo__f1
    print('Foo.f1')

    def f2(self):
    print('Foo.f2')#在类定义阶段变形成Foo__f2
    self.__f1() #这里调用自己,不会和Bar里面的f1冲突

    class Bar(Foo):
    def __f1(self): #在定义阶段变形成Bar__f1
    print('Bar.f1')

    obj=Bar()
    obj.f2()

    PS:想访问的方法就是访问自己,把方法变成赢藏的,然后在一个地方调用,一定不会和别的同名的冲突,为什么不会冲突,因为在类定义阶段大家都统一进行了变形,变形规则就是自己的类名,所以和别人冲突不了,类名是不会重复的

    为什么要封装

    1、封装数据属性

    意图:将数据隐藏起来,从而类的使用者无法直接操作该数据属性,需要类的设计者在类的内部开辟接口,让类的使用者用过接口来间接的操作数据,类的设计者可以在接口之上附加任意逻辑,从而严格控制类的使用者对属性的操作

    隐藏数据属性的目的:
    class People:
    def __init__(self,name,age):
    self.__name=name
    self.__age=age

    def tell_info(self): #类内部开了一个接口让外部访问,还可以定制访问格式
    print('<Name:%s Age:%s>' %(self.__name,self.__age))

    def set_info(self,name,age): #类内部开了一个修改接口,可以限定外部传入的格式
    if type(name) is not str:
    print('名字必须是str类型傻叉')
    return
    if type(age) is not int:
    print('年龄必须是int类型傻叉')
    return
    self.__name=name #这里就可以限定用户修改的格式,而不能直接修改
    self.__age=age

    def del_info(self): #删除用户名和密码也是,只能从类内部删除,将删除代码放入一个函数,存在类的内部,需要删除时候调用这个函数
    del self.__name
    del self.__age

    obj=People('egon',18)
    obj.tell_info() #这里通过接口访问到数据

    obj.set_info('EGON',19)
    obj.tell_info()#这里通过接口修改了数据

    obj.del_info()
    print(obj.__dict__)

    PS:封装数据可以在接口之上附加任意设计者想要的逻辑,比如严格控制用户对属性的增删该查操作,比如修改用户名字的格式等

     2、封装函数

    意图:比如取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做隔离了复杂度,同时也提升了安全性

    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()
    
    a=ATM()
    a.withdraw()
    
    
  • 相关阅读:
    Docker简介
    分类技术
    龙果支付系统
    [徐培成系列实战课程]docker篇
    高手速成android开源项目【developer篇】
    高手速成android开源项目【项目篇】
    高手速成android开源项目【tool篇】
    高手速成android开源项目【View篇】
    JAVA代理分析
    程序员的2013回顾及2014钱途
  • 原文地址:https://www.cnblogs.com/shizhengquan/p/10093374.html
Copyright © 2011-2022 走看看