当前位置: 首页 > news >正文

python之路----面向对象的封装特性

封装

【封装】

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

狭义上的封装 —— 面向对象的三大特性之一:属性 和 方法都藏起来 不让你看见

【好处】 

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__N

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

 
 

私有方法

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

#正常情况
>>> 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

相关文章:

  • DAY9-字符串笔记整理2018-1-19
  • 新建一个虚拟机
  • Android layer-list的属性和使用具体解释
  • 安全地关闭 jvm(tomcat停止钩子事件处理)
  • 智慧医疗“验血查癌”或会实现
  • shell脚本练习题
  • 沉浸式状态栏解析
  • 若要允许 GET 请求,请将 JsonRequestBehavior 设置为 AllowGet
  • Spring Cloud微服务分布式云架构简介
  • centos7 mysql 5.7 yum安装
  • Maven单独构建多模块项目中的单个模块
  • 常用页面校验整合
  • java spring事务管理相关
  • HTML5 a标签的download属性
  • 正向代理,反向代理(图片解析)
  • ES6指北【2】—— 箭头函数
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • Android单元测试 - 几个重要问题
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • CSS相对定位
  • Mysql数据库的条件查询语句
  • spring-boot List转Page
  • Spring-boot 启动时碰到的错误
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 工作手记之html2canvas使用概述
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 用jQuery怎么做到前后端分离
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #每日一题合集#牛客JZ23-JZ33
  • #微信小程序:微信小程序常见的配置传旨
  • (HAL库版)freeRTOS移植STMF103
  • (js)循环条件满足时终止循环
  • (二)换源+apt-get基础配置+搜狗拼音
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (二十三)Flask之高频面试点
  • (算法)Travel Information Center
  • (已解决)什么是vue导航守卫
  • (转)nsfocus-绿盟科技笔试题目
  • (转)Oracle存储过程编写经验和优化措施
  • (转)平衡树
  • (转)为C# Windows服务添加安装程序
  • (转载)虚函数剖析
  • .NET 5种线程安全集合
  • .NET 8.0 中有哪些新的变化?
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET 设计模式初探
  • .Net 应用中使用dot trace进行性能诊断
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • .NET成年了,然后呢?
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?