面向对象编程 -- 封装、继承

面向对象编程三要素:封装、继承和多态。本文主要看和封装、继承相关的概念;在python中多态的概念比较模糊,本文不做讨论。

1 封装

封装:将数据和操作组装到一起,对外只暴露一些接口供类外部或子类访问,隐藏数据和操作的实现细节。

在其他面向对象语言,比如java中,属性访问控制一般有三种状态:private、protectd、public。python中没有什么东西是完全不可见的,没有任何机制可以强制性的隐藏数据。所以在python中不存在真正的只能在对象内部访问的属性。
一个被大多数的python程序员遵守的约定:以下划线开头的变量应该被当作非公有属性对待,即它应该被当作是实现细节,其修改应该是不被察觉的。

1.1 名称管理

python中有一种机制对类成员的私有化提供有限的支持,称为名称管理
任何以至少两个下划线开头、至多一个下划线结尾的标识符,如__spam,都会被转换为_classname__spam的形式,其中classname是当前的类名。这种名称管理机制不考虑标识符实际归属哪个命名空间,只要它发生在类的定义中,就会自动生效。

class Chinese:"""A sample example class"""nationality = 'China'def __init__(self, name, age, gender):self.name = nameself.__age = ageself.gender = genderdef __str__(self):return '{}(name={}, age={}, gender={})'.format(self.__class__, self.name, self.__age, self.gender)xm = Chinese('xiaoming', 18, 'male')
print(xm.__dict__)  # {'gender': 'male', 'name': 'xiaoming', '_Chinese__age': 18}
print(xm)           # <class '__main__.Chinese'>(name=xiaoming, age=18, gender=male)
print(xm.__age)     # AttributeError: 'Chinese' object has no attribute '__age'

  • __age在类中被自动转化为_Chinese__age保存在实例的命名空间中;
  • 类内部出现的__age形式的标识符都会被自动转换,所以__str__方法可以访问本例中的__age属性;
  • 在类外部(包括在子类中),无法访问__age属性,因为实例命名空间中并不存在该属性。

继承

继承:对现有类的一种复用机制。如果相对现有的类做一些个性化的修改,可以通过继承实现,而不是直接修改原类。

python的继承语法如下:

class DerivedClassName(BaseClassName):<statement-1>...<statement-N>

BaseClassName代表被继承的类,称为基类或者父类。
DerivedClassName称为子类。除了添加了父类,子类的定义和实例化和普通的类并没有什么区别。可以通过BaseClassName.__bases__查看其父类。

  1. 子类可以引用父类命名空间中的所有属性。属性的查找顺序:实例-->子类-->父类-->父类的父类...-->object。python3中所有的类都隐性继承自object类。
  2. 子类可以重写父类的属性。一旦属性重写,对于子类或子类之前开始的属性查找,父类对应的属性相当于被屏蔽掉了。
  3. 如果子类要重写初始化方法,最好通过扩展父类的初始化方法实现,即调用父类的初始化方法,并实现自己的个性化扩展。
class Animal:def __init__(self, name, age):self.name = nameself.age = agedef reply(self):return self.speak()def speak(self):return 'Hello world'class Cat(Animal):def __init__(self, name, age, breed):super().__init__(name, age)self.breed = breeddef speak(self):return 'Cat Miaow'print(Cat.__bases__)    # (<class '__main__.Animal'>,)
garfield = Cat('Garfield', 10, 'Garfield')
print(garfield.reply()) # Cat Miaow

super().__init__引用Animal之前的祖先类的初始化方法。

多继承

python是支持多继承的,其语法如下:

class DerivedClassName(Base1, Base2, Base3):<statement-1>...<statement-N>

多继承要解决的主要问题是属性搜索顺序:
1. 将类及其祖先类按照搜索优先级从高到低排列生成一个列表的过程称为类的线性化。
2. MRO: Method Resolution Order, 指用于类线性化的规则,python3用的是C3算法。C3算法可以保证线性化的单调性,单调性是指:如果在类C的线性化中,C1的优先级高于C2,那么C的所有子类的线性化中,C1的优先级高于C2。
3. 可以通过 DerivedClassName.__mro__ 查看类的线性化结果。

想了解C3算法的具体实现,可以参考文章:https://www.python.org/download/releases/2.3/mro/

其他

数据属性和方法属性可能会出现标识符冲突,这会导致非预期的属性重写(对于标识符而言,赋值即定义),这在大型项目中会引起难以定位的bugs。为了避免标识符冲突,使用一些约定最小化冲突概率是明智的。参考方案:

  • 大写方法属性的首字母,给数据属性标识符添加特定的前缀
  • 使用动词标识方法属性,使用名词标识数据属性

参考:

1 file:///Library/Frameworks/Python.framework/Versions/3.5/Resources/English.lproj/Documentation/tutorial/classes.html

转载于:https://www.cnblogs.com/52py/p/8074570.html

python面向对象编程 -- 封装、继承相关推荐

  1. python面向对象编程(封装与继承)

    一. 面向过程编程语言 "面向过程"(Procedure Oriented)是一种以过程为中心的编程思想.分析出解决问题所需要的步 骤,然后用函数把这些步骤一步一步实现,使用的时候 ...

  2. 面向对象编程 封装 继承 多态(三大特征)(第三篇)

    封装 封装是面向对象编程的三大特征之一. 封装有两方面的含义: 1.将数据(属性)和行为(方法)包装到类对象中.方法内部对属性进行操作,在类对象的外部调用方法.这样,无需关心方法内部的具体实现细节,从 ...

  3. Python - 面向对象编程 - 多继承

    继承的详解 https://www.cnblogs.com/poloyy/p/15216652.html 这篇文章讲的都是单继承,Python 中还有多继承 Python 多继承的背景 大部分面向对象 ...

  4. Python零基础速成班-第9讲-Python面向对象编程(上),对象和类、初始化、继承、重写、多态、类方法、组合

    Python零基础速成班-第9讲-Python面向对象编程(上),对象和类.初始化.继承.重写.多态.类方法.组合 学习目标 修饰器 面向对象编程:对象和类.初始化.继承.重写.多态.类方法.组合 课 ...

  5. Python面向对象编程:类继承和其衍生术语

    Python面向对象编程03:类继承和其衍生术语 前面我们讲到过正则表达式字符等,上一篇分享了面向对象编程和类的结构,最后稍微提到了继承. Python面向对象编程:深度认识类class_ Pytho ...

  6. python对象编程例子-这是我见过最详细的Python面向对象编程!建议收藏!

    原标题:这是我见过最详细的Python面向对象编程!建议收藏! 面向对象编程和函数式编程(面向过程编程)都是程序设计的方法,不过稍有区别. 面向过程编程: 1. 导入各种外部库 2. 设计各种全局变量 ...

  7. 【Python基础】Python 面向对象编程(上篇)

    我的施工计划图 已完成专题包括: 1我的施工计划 2数字专题 3字符串专题 4列表专题 5流程控制专题 6编程风格专题 7函数使用专题 今天是面向对象编程的上篇:基础专题 Python 面向对象编程 ...

  8. python面向对象编程138讲_Python面向对象编程简单讲解

    学习目标: 1-面向对象编程 2-类和对象 3-对象的属性和方法 4-类的特性 Python面向对象编程 一种编程程序的设计思想,把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数.把计算机 ...

  9. (转)Python 面向对象编程(一)

    Python 面向对象编程(一) 虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程.下面就来了解一下如何在Python中进行对象编程. 一.如何定义一个类 在进行python面向对象 ...

最新文章

  1. pandas打乱行次序
  2. java进销存培训_Java实例学习——企业进销存管理系统(2)
  3. 实验九 根据材料编程(改变字体颜色)
  4. “让数据用起来”:解读数据中台必备的4个核心能力
  5. 苹果x和xsmax有什么区别_苹果手机不卡的真相是什么,安卓和iOS有本质区别
  6. 阿里题目:明星群众问题
  7. html中div的居中
  8. 绝对定位的图 说明初始包含块是viewport 而不是body/html
  9. 菜鸟电子面单ISV云打印组件一致性改造心得
  10. 韦东山Linux嵌入式学习——硬件复习
  11. 出自蚂蚁课堂的简单springboot-demo
  12. Linux:什么是 i386、i586、 i686、noarch?
  13. 使用bus hound发送包的方法
  14. SAR—距离向脉冲压缩的一些理解
  15. 同比增长和环比增长的区别
  16. 用防火墙自动拦截攻击IP
  17. 公众号和知乎排版神器 - mdnice.com
  18. 河南省软考报名时间成绩查询河南省教育考试院河南省人事考试网报名入口
  19. 如何把视频转换成gif动图
  20. html 图片 空白,HTML图片标签空白解决方法

热门文章

  1. MySQL太细碎了,我硬生生捋出了一条核心大主线!
  2. 一款 Java 开源的 Spring Boot 即时通讯 IM 聊天系统
  3. JDK1.8源码分析:线程安全的CopyOnWriteArrayList与CopyOnWriteArraySet
  4. 高效开发:IntelliJ IDEA天天用,这些Debug技巧你都知道?
  5. 聊一聊 Java 服务端中的乱象
  6. Spring Boot 静态资源处理,妙!
  7. 15万奖金强化学习赛事!Go-Bigger多智能体决策智能挑战赛来了!
  8. 拖拽公式图片、一键转换LaTex公式,这款开源公式识别神器比Mathpix Snip更适合你...
  9. 总结2021面试中的常见14种算法套路
  10. 27岁华裔小伙一战成名!搞出美国新冠最准预测模型