博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python之路----面向对象的封装特性
阅读量:7232 次
发布时间:2019-06-29

本文共 2825 字,大约阅读时间需要 9 分钟。

封装

【封装】

隐藏对象的属性和实现细节,仅对外提供公共访问方式。
广义上面向对象的封装 :代码的保护,面向对象的思想本身就是一种只让自己的对象能调用自己类中的方法狭义上的封装 —— 面向对象的三大特性之一:属性 和 方法都藏起来 不让你看见

【好处】 

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是可以访问到的,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形
 

这种自动变形的特点:

1.类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。2.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。3.在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。
 

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

 
1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N2.变形的过程只在类的内部生效,在定义后的赋值操作,不会变形

 

私有方法

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

#正常情况>>> 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 Person:    __key = 123  # 私有静态属性    def __init__(self,name,passwd):        self.name = name        self.__passwd = passwd   # 私有属性    def __get_pwd(self):         # 私有方法        return self.__passwd   #只要在类的内部使用私有属性,就会自动的带上_类名    def login(self):          # 正常的方法调用私有的方法        self.__get_pwd()alex = Person('alex','alex3714')print(alex._Person__passwd)   # _类名__属性名print(alex.get_pwd())所有的私有 都是在变量的左边加上双下划綫
结合练习

封装与扩展性

封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码;而外部使用用者只知道一个接口(函数),只要接口(函数)名、参数不变,使用者的代码永远无需改变。这就提供一个良好的合作基础——或者说,只要接口这个基础约定不变,则代码改变不足为虑。

#类的设计者class Room:    def __init__(self,name,owner,width,length,high):        self.name=name        self.owner=owner        self.__width=width        self.__length=length        self.__high=high    def tell_area(self): #对外提供的接口,隐藏了内部的实现细节,此时我们想求的是面积        return self.__width * self.__length#使用者>>> r1=Room('卧室','egon',20,20,20)>>> r1.tell_area() #使用者调用接口tell_area#类的设计者,轻松的扩展了功能,而类的使用者完全不需要改变自己的代码class Room:    def __init__(self,name,owner,width,length,high):        self.name=name        self.owner=owner        self.__width=width        self.__length=length        self.__high=high    def tell_area(self): #对外提供的接口,隐藏内部实现,此时我们想求的是体积,内部逻辑变了,只需求修该下列一行就可以很简答的实现,而且外部调用感知不到,仍然使用该方法,但是功能已经变了        return self.__width * self.__length * self.__high#对于仍然在使用tell_area接口的人来说,根本无需改动自己的代码,就可以用上新功能>>> r1.tell_area()
 
 

转载于:https://www.cnblogs.com/TheLand/p/8310667.html

你可能感兴趣的文章
tt安装与配置
查看>>
software testing HW02
查看>>
linux .net mono方案测试记录与报告(一)
查看>>
某未被少林寺吞并的小寺庙师徒的经典对话
查看>>
IT兄弟连 JavaWeb教程 JSP内置对象1
查看>>
IT兄弟连 JavaWeb教程 JSP内置对象经典案例
查看>>
XCode环境变量及路径设置 解决头文件找不到的问题
查看>>
[Go]链表的相关知识
查看>>
C# Json数据反序列化为Dictionary并根据关键字获取指定值1
查看>>
jS Ajax 上传文件报错"Uncaught TypeError: Illegal invocation"
查看>>
javascript、jquery获取网页的高度和宽度
查看>>
面向对象---代码练习(以车为案例)
查看>>
C#趋势图(highcharts插件)
查看>>
stm32的flash编程
查看>>
java多线程-AbstractQueuedSynchronizer
查看>>
苹果新的编程语言 Swift 语言进阶(十四)--扩展
查看>>
Md5加密方法
查看>>
转:zookeeper中Watcher和Notifications
查看>>
函数的参数
查看>>
Java编程规范
查看>>