day26---面向对象封装

1. 封装

  • 定义:把属性和方法放在类中,只能类内调用,不能在类外调用

  • 优点:

    • 将变化隔离
    • 便于使用
    • 提高复用性
    • 提高安全性
  • 原则:

    • 将不需要对外的内容隐藏起来
    • 把属性隐藏,提供公共方法对其访问

2. 私有变量和私有方法

  • 私有:在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)

  • 定义:__名字

  • 调用:

    • 在类中调用:__名字
    • 在类外不能直接使用,必须使用使用:_类名__名字(如果外部必须调用,也没有必要设置私有属性或方法了,所以不允许这样使用)
  • 继承:python中的封装只有公有(默认方式)和私有两种方式,没有受保护的方式,所以在python中私有的变量、属性和方法都是无法继承的

class Animal:
        __country = 'China'
        def __init__(self, name):
            self.__name = name
        def __func(self):
            print(self.__country)
yan = Animal('岩哥')
print(yan.country)  # 报错
print(yan.__name)  # 报错
print(Animal.__dict__)
print(yan.__func)  # 报错
print(yan._Animal__country)
print(yan._Animal__name)
yan._Animal__func()
>>>
        print(yan.country)
AttributeError: 'Animal' object has no attribute 'country'
        print(yan.__name)
AttributeError: 'Animal' object has no attribute '__name'
{'__module__': '__main__', '_Animal__country': 'China', '__init__': <function Animal.__init__ at 0x000002156ADD88C8>, '_Animal__func': <function Animal.__func at 0x000002156ADD8950>, '__dict__': <attribute '__dict__' of 'Animal' objects>, '__weakref__': <attribute '__weakref__' of 'Animal' objects>, '__doc__': None}
        print(yan.__func)
AttributeError: 'Animal' object has no attribute '__func'
China
岩哥
China
class Animal:
        def __func(self):
            print('Animal...')
class Person(Animal):
        def __init__(self):
            self.__func()
yan = Person()
yan.func()
>>>
        self.__func()
AttributeError: 'Person' object has no attribute '_Person__func'

3. 内置函数

  • property:把一个方法伪装成一个属性。伪装之后,属性的值就是方法的返回值,然而方法就不能有参数了

    • 最适合的组合:__私有的+property
    class Fruits:
            __discount = 0.8
            def __init__(self, name, price):
                self.__name = name
                self.__price = price
        
            @property
            def sale(self):
                return self.__price * Fruits.__discount
    apple = Fruits('苹果', 100)
    # print(apple.sale())
    print(apple.sale)
    >>>
    80.0
    
      * ###### 让对象的属性变的更加安全
      * ###### 所获取到对象的值可以进行操作
      * ###### 这对对象的值进行进一步的安全验证
      * ###### 修改对象的值
      * ###### 删除对象的值
    
    • 修改伪装的属性:@方法名.setter
    class Fruits:
            __discount = 0.8
            def __init__(self, name, price):
                self.__name = name
                self.__price = price
            @property
            def price(self):
                return self.__price * Fruits.__discount
            @price.setter
            def price(self, new_price):
                self.__price = new_price
    apple = Fruits('苹果', 100)
    print(apple.__dict__)
    print(apple.price)
    apple.price = 200
    print(apple.__dict__)
    print(apple.price)
    >>>
    {'_Fruits__name': '苹果', '_Fruits__price': 100}
    80.0
    {'_Fruits__name': '苹果', '_Fruits__price': 200}
    160.0
    
    • 删除伪装的属性:@方法名.deleter
    class Fruits:
            __discount = 0.8
            def __init__(self, name, price):
                self.__name = name
                self.__price = price
            @property
            def price(self):
                return self.__price * Fruits.__discount
            @price.setter
            def price(self, new_price):
                self.__price = new_price
            @price.deleter
            def price(self):
                del self.__price
    apple = Fruits('苹果', 100)
    print(apple.__dict__)
    print(apple.price)
    apple.price = 200
    print(apple.__dict__)
    print(apple.price)
    del apple.price
    print(apple.__dict__)
    print(apple.price)
    >>>
    {'_Fruits__name': '苹果', '_Fruits__price': 100}
    80.0
    {'_Fruits__name': '苹果', '_Fruits__price': 200}
    160.0
    {'_Fruits__name': '苹果'}
            return self.__price * Fruits.__discount
    AttributeError: 'Fruits' object has no attribute '_Fruits__price'
    
  • classmethod:

    • 定义:classmethod时一个类方法
    • 描述:不用接收self参数,默认转cls参数(cls代表当前方法所在的类)
    • 调用:不需要实例化,直接使用类名调用
    • 原则:
      • 需要使用静态变量
      • 不需要和对象相关做任何操作
    class A:
                @classmethod
                def func1(self):
                    print('classmethod---self...')
                def func2(cls):
                    print('classmethod---cls...')
    a = A()
    a.func1()
    a.func2()
    >>>
    classmethod---self...
    classmethod---cls...
    
  • staticmethod

    • 定义:staticmethod是一个静态方法
    • 描述:staticmethod可以当作普通的函数用,只不过调用的时候使用类名.函数名调用,传参数、返回值等都跟函数一样使用
    • 原则:
      • 不需要操作静态变量
      • 不需要使用对象相关操作
    class A:
                @staticmethod
                def func(n):
                    return n**2
    a = A()
    print(a.func(8))
    >>>
    64
    
  • 类方法和静态方法都可以直接使用类名调用,普通方法需要使用对象调用

  • 类方法绑定到了类的方法上,普通方法绑定到了对象的方法上

class A:
        @staticmethod
        def func1():
            print(123)
        @classmethod
        def func2(cls):
            print(123)
        def func3(self):
            pass
a = A()
print(a.func1)
print(a.func2)
print(a.func3)
>>>
<function A.func1 at 0x000001C7F88E88C8>
<bound method A.func2 of <class '__main__.A'>>
<bound method A.func3 of <__main__.A object at 0x000001C7F88EA470>>
posted @ 2017-11-22 16:49  _岩哥  阅读(98)  评论(0)    收藏  举报