面向对象的三大特性 - 封装

阅读目录:

概念

【封装】

         隐藏对象的属性和实现细节,仅对外提供公共访问方式。

【好处】 

1. 将变化隔离; 

2. 便于使用;

3. 提高复用性; 

4. 提高安全性;

【封装原则】

      1. 将不需要对外提供的内容都隐藏起来;

      2. 把属性都隐藏,提供公共方法对其访问。

私有变量和私有方法

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

私有变量

#其实这仅仅这是一种变形操作
#类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式:

class A:
    __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N
    def __init__(self):
        self.__X=10 #变形为self._A__X
    def __foo(self): #变形为_A__foo
        print('from A')
    def bar(self):
        self.__foo() #只有在类内部才可以通过__foo的形式访问到.

#A._A__N是可以访问到的,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形
class Dog:
    # dog_sum = 0         # 不安全,因为这个属性可以在类的外部被随便修改
    __dog_sum = 0         # 安全,通过dog_sum方法和__变量名让属性变成只能看不能改的值
    def __init__(self):
        self.count()
    def count(self):
        Dog.__dog_sum += 1 # 可以从一个类的内部使用__dog_sum的属性
    def dog_sum(self):
        return Dog.__dog_sum

print(Dog.__dict__)
alex = Dog()
print(Dog.__dict__)
# print(Dog.__dog_sum)    # 不可以从外部直接使用这个变量
print(alex.dog_sum())

这种自动变形的特点:

1.类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果

2.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。

3.在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。

 

这种变形需要注意的问题是:

1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N

2.变形的过程只在类的内部生效,在定义后的赋值操作,不会变形

 

私有方法

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

#正常情况
>>> class A:
...     def fa(self):
...         print('from A')
...     def test(self):
...         self.fa()
... 
>>> class B(A):
...     def fa(self):
...         print('from B')
... 
>>> b=B()
>>> b.test()
from B
 

#把fa定义成私有的,即__fa
>>> class A:
...     def __fa(self): #在定义时就变形为_A__fa
...         print('from A')
...     def test(self):
...         self.__fa() #只会与自己所在的类为准,即调用_A__fa
... 
>>> class B(A):
...     def __fa(self):
...         print('from B')
... 
>>> b=B()
>>> b.test()
from A

子类不能继承父类的私有方法

 

class Foo(object):
    def __init__(self):
    self.
__func() # _Foo__func
def __func(self):print('in Foo __func') # _Foo__func
def func(self):print('in Foo func')
class Son(Foo):
def __func(self):print('in Son __func') # _Son__func
def func(self):print('in Son func') Son()
执行结果:
in Foo __func

class Foo(object):
    def __init__(self):
        self.func()    # _Foo__func

def __func(self):print('in Foo __func') # _Foo__func

def func(self):print('in Foo func') class Son(Foo):
def __func(self):print('in Son __func') # _Son__func

def func(self):print('in Son func') Son() 执行结果:in Son __func

 

posted @ 2019-02-07 01:58  小萍瓶盖儿  阅读(131)  评论(0)    收藏  举报