zoukankan      html  css  js  c++  java
  • 封装之如何隐藏对象及封装的意义

    python中通常在属性和方法前加__(两条下划线)来进行属性和方法的隐藏。

    特点:

    1.在类外无法直接obj.__AttrName

    2.在类内部可以直接使用obj.__AttrName

    3.子类无法覆盖父类__开头的属性

    1.在类外无法直接obj.__AttrName

    class A:
        def __init__(self, name, life):
            self.__name = name
            self.__life = life
    
        def __run(self):
            print('run')
    
        def sing(self):
            self.__run()
            print('sing')
    
    b = A('gaohui', 100)
    print(b.__name)
    
    
    报错:
    AttributeError: 'A' object has no attribute '__name'

    2.在类内部可以直接使用obj.__AttrName

    class A:
        def __init__(self, name, life):
            self.__name = name
            self.__life = life
    
        def __run(self):
            print('run')
    
        def sing(self):
            self.__run()
            print('sing')
    
    b = A('gaohui', 100)
    b.sing()
    
    输出结果:
    run
    sing

    此时的__run正常输出了,因为在类的定义时,self.__run()已经便成了self._A__run()

    3.子类无法覆盖父类__开头的属性

    class A:
        def __init__(self, name, life):
            self.__name = name
            self.__life = life
    
        def __run(self):
            print('run')
    
        def sing(self):
            self.__run()
            print('sing')
    
    class B(A):
        def __init__(self, name, age, life):
            super().__init__(name, age)
            self.__life = life
    
        def __run(self):
            print('---')
            
    
    print(A.__dict__)
    print(B.__dict__)
    
    
    输出结果:
    {'__module__': '__main__', '__init__': <function A.__init__ at 0x1068190d0>, '_A__run': <function A.__run at 0x1068192f0>,
    {'__module__': '__main__', '__init__': <function B.__init__ at 0x106819730>, '_B__run': <function B.__run at 0x1068197b8>,
    
    两个run方法的属性是不一样的。

    方法和属性隐藏需要注意的地方:

    1.外部不能直接饮用,需要对象._类__属性的形式可以提出隐藏的属性和方法

    2.变形的过程只有在类的定义时发生一次,再次赋值时不会变形。

    3.在继承中,如果父类不想让子类覆盖自己的方法,可以将方法定义为私有的。

    1.外部不能直接饮用,需要对象._类__属性的形式可以提出隐藏的属性和方法

    class A:
        def __init__(self, name, life):
            self.__name = name
            self.__life = life
    
        def __run(self):
            print('run')
    
        def sing(self):
            self.__run()
            print('sing')
    
    a = A('gaohui', 100)
    print(a._A__name)
    
    
    输出结果:
    gaohui

    2.变形的过程只有在类的定义时发生一次,再次赋值时不会变形。

    class A:
        def __init__(self, name, life):
            self.__name = name
            self.__life = life
    
        def __run(self):
            print('run')
    
        def sing(self):
            self.__run()
            print('sing')
    
    A.__b = 1
    a = A('gaohui', 100)
    print(a._A__name)
    print(A.__b)
    
    
    输出结果:
    gaohui
    1

    当类已经定义好了,再次定义时不会变形成隐藏的模式。

    3.在继承中,如果父类不想让子类覆盖自己的方法,可以将方法定义为私有的。

    class A:
        def __fa(self):     *_A__fa
            print('from A')
    
        def test(self):
            self.__fa()  # 此时的fa方法是变形过的_A__fa,所以之行类A中的fa方法
    
    
    class B(A):
        def __fa(self):    *_B__fa
            print('from B')
    
    
    b = B()
    b.test()
    
    
    输出结果:
    
    from A

    封装数据属性的意义:明确的区分内外,控制外部对隐藏的属性的操作行为

    class A:
        def __init__(self, name, age):
            self.__name = name
            self.__age = age
    
        def tell_info(self):        # 可以通过一个接口来显示被隐藏的数据,不能直接被外部调用
            print('name is %s, age is %s' % (self.__name, self.__age))
    
        def search_info(self, name, age):
            if not isinstance(name, str):  # 检验是不是字符串
                print('姓名为字符串')
                return
            if not isinstance(age, int):
                print('年龄已经为整数')
                return
            self.__name = name
            self.__age = age
            self.tell_info()
    
    
    st = A('GAO', 23)
    print(st.__dict__)
    #st.search_info('Gww', 23)  # 可以通过一个接口来修改name和age,而不是直接修改

    封装方法:

    class ATM:
        def __card(self):
            print('插卡')
    
        def __auth(self):
            print('用户验证')
    
        def __input(self):
            print('输入取款金额')
    
        def withdraw(self):
            self.__card()
            self.__auth()
            self.__input()
    
    
    a = ATM()
    a.withdraw()
  • 相关阅读:
    robotframework-requests--中文注解版
    Python猜数小游戏
    走进Selenium新世界
    HTML
    Web测试方法_02
    3.线程死锁
    2.线程--线程安全(synchronized)
    1.线程--线程创建方式
    使用Android-studio开发移动app与weex结合开发详细步骤
    Weex 简介
  • 原文地址:https://www.cnblogs.com/huizaia/p/9670021.html
Copyright © 2011-2022 走看看