写给小白的Python之017:面向对象-封装、继承、…
2018-06-18 02:52:07来源:未知 阅读 ()
1. 封装
面向对象三大特性:封装、继承、多态
封装(Encapsulation):这是定义类的 准则,单个类。根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中。
封装的意义:
1.将属性和方法放到一起做为一个整体,然后通过实例化对象来处理;
2.隐藏内部实现细节,只需要和对象及其属性和方法交互就可以了;
3.对类的属性和方法增加 访问权限控制。
2. 继承
继承:这是设计类的 技巧,父与子。
- 主要体现是实现代码的 重用,相同的代码不需要重复的编写;
- 子类可以在父类功能上进行重写,扩展类的功能。
在面向对象编程中,当我们已经创建了一个类,而又想再创建一个与之相似的类,比如添加几个方法,或者修改原来的方法,这时我们不必从头开始,可以从原来的类派生出一个新的类, 我们把原来的类称为父类或基类,而派生出的类称为子类或派生类,子类继承了父类的所有数据和方法。
从技术上说, OOP里继承最主要的用途是实现多态。对于多态而言,重要的是接口继承性,属性和行为是否存在继承性,这是不一定的。事实上, 大量工程实践表明,重度的行为继承会导致系统过度复杂和臃肿,反而会降低灵活性。因此现在比较提倡的是基于接口的轻度继承理念。这种模型里因为父类(接口类)完全没有代码,因此根本谈不上什么代码复用。
2.1 单继承
子类的定义如下:
class 子类名(父类名):
<statement-1>
...
<statement-N>
父类名 BaseClassName 对于子类来说必须是可见的。也可以继承在其他模块中定义的父类:
class 子类名(模块名.父类名):
对于子类的属性引用:首先会在当前的子类中搜索,如果没有找到,则会递归地去父类中寻找。
从C++术语上讲,Python 类中所有的方法都是 vitual 的,所以子类可以覆写(override)父类的方法。在子类中一个覆写的方法可能需要调用父类的方法,可以通过以下方式:
父类名.方法(self, arguments)
2.2 多继承
Python支持多继承,一个多继承的定义形如:
class 子类名(父类名1, 父类名2, 父类名3):
多个父类有同名属性和方法
子类的魔法属性__mro__决定了属性和方法的查找顺序。如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性mro的顺序来查找)。
子类重写父类的属性和方法
子类和父类的方法名和属性名相同,则默认使用子类的,叫 子类重写父类的同名方法和属性。
使用重写的目的:当子类发现父类的大部分功能都能满足需求,但是有一些功能不满足,则子类可以重写父类方法。
2.3 调用父类方法
重写之后,如果发现仍然需要父类方法,则可以强制调用父类方法。
方法1. 指定执行父类的方法
无论何时何地,self都表示是子类的对象。在调用父类方法时,通过传递self参数,来控制方法和属性的访问修改。通常用于多继承。
- 父类名.父类方法(self, 参数列表)
- 父类名().属性/方法 # 不推荐这样访问父类的实例属性,相当于创建了一个新的父类对象
子类继承了多个父类,如果父类类名修改了,那么子类也要涉及多次修改。而且需要重复写多次调用,显得代码臃肿。
方法2. super() 带参数版本
只支持新式类,支持Python2和3。工作中使用这个。
- super(子类名, self).父类方法(参数列表)
# super(子类名, self).__init__() # 执行父类的 __init__方法
# self.方法名()
示例:
class Animal: def __init__(self, age): # 1.父类有时候需要接收一些参数 self.age = age class Cat(Animal): def __init__(self, age): # 3.一般情况下,父类需要的参数,子类也是动态来获取 self.name = '伊丽莎白' super(Cat, self).__init__(age) # 2.子类需要为父类传递实参 cat = Cat(12) # 4. 根据子类需求,传递对应的实参 print(cat.age) # 12
方法3. super()的简化版
只支持新式类,只支持Python3
- super().父类方法(参数列表) # 执行父类的 实例方法
super().__init__() # 执行父类的 __init__方法
知识点:
- 使用super() 可以逐一调用所有的父类方法,并且只执行一次。调用顺序遵循 mro 类属性的顺序。
- 注意:如果继承了多个父类,且父类都有同名方法,则默认只执行第一个父类的(同名方法只执行一次,目前super()不支持执行多个父类的同名方法)
- super() 在Python2.3之后才有的机制,用于通常单继承的多层继承。
3. 多态
多态是指对不同类型的变量进行相同的操作,它会根据对象(或类)类型的不同而表现出不同的行为。即 不同类的对象调用相同方法,产生不同的结果。
多态(Polymorphism):
- 不同的子类对象调用相同的父类方法,产生不同的 执行结果;父类能工作的地方,子类都能工作;
- 多态以继承和重写父类方法为前提;
- 多态是调用方法的技巧,不会影响到类的内部设计。
多态的好处:
在保证安全性的前提下,提高了方法调用的灵活性。
多态的实现:
1.定义一个父类
2.定义多个子类,并重写父类的方法
3.传递子类对象给调用者,不同子类对象能产生不同执行效果
示例:
class Dog(object): def work(self): # 父类提供统一的方法,哪怕是空方法 pass class ArmyDog(Dog): # 继承 Dog def work(self): # 子类重写方法,并且处理自己的行为 print('追击敌人') class DrugDog(Dog): def work(self): print('追查毒品') class Person(object): def work_with_dog(self, dog): dog.work() # 使用小狗可以根据对象的不同而产生不同的运行效果, 保障了代码的稳定性 # 子类对象可以当作父类来使用 dog = Dog() print(isinstance(dog, Dog)) # True ad = ArmyDog() print(isinstance(ad, Dog)) # True dd = DrugDog() print(isinstance(dd, Dog)) # True p = Person() p.work_with_dog(dog) p.work_with_dog(ad) # 同一个方法,只要是 Dog 的子类就可以传递,提供了代码的灵活性 p.work_with_dog(dd) # 并且传递不同对象,最终 work_with_dog 产生了不同的执行效果 # 最终效果 # Person 类中只需要调用 Dog 对象 work() 方法,而不关心具体是 什么狗 # work() 方法是在 Dog 父类中定义的,子类重写并处理不同方式的实现 # 在程序执行时,传入不同的 Dog 对象作为实参,就会产生不同的执行效果
多态总结:
# 定义:多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果。
# 好处:调用灵活,有了多态,更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化!
鸭子类型:
动态语言的“鸭子类型”(duck typeing),它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。即只要一个对象相似的属性和方法。
动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的。
类型检查是毁掉多态的利器, 比如type、 isinstance以及isubclass函数,所以,一定要慎用这些类型检查函数。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- python3基础之“术语表(2)” 2019-08-13
- python3 之 字符串编码小结(Unicode、utf-8、gbk、gb2312等 2019-08-13
- Python3安装impala 2019-08-13
- 小白如何入门 Python 爬虫? 2019-08-13
- python_字符串方法 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash