7.面向对象三大特性
2018-08-16 本文已影响10人
芝麻酱的简书
特性1 继承:
class Dad:
"这是爹"
id_num = 123
def __init__(self, name):
self.name = name
class Son(Dad):
pass
print(Dad.__dict__)
print(Son.__dict__)
接口继承与归一化设计:
使用abc
(Abstract Bass Class)模块
import abc
class Dad(metaclass=abc.ABCMeta):
# 声明抽象方法
@abc.abstractmethod
def __init__(self, name):
self.name = name
class Son(Dad):
# 子类必须实现父类的抽象方法__init__
pass
多继承:
Python多继承,属性寻找方法有两种:
- 深度优先
- 广度优先
例如上图继承关系,W继承自D和E,W中的查找关系是:
①深度优先的话:W -> D -> B -> A -> E -> C
②广度优先的话:W -> D -> B --> E -> C -> A
经典类多继承情况下,会按照深度优先的方式查找,python2中,通通过查看根类是新式类还是经典类来判断子类的类型;
新式类多继承情况下,会按照广度优先的方式查找,python3中全部都是新式类;
对于我们定义的类,python会计算出一个方法解析顺序MRO列表,也就是一个简单的所有基类的线性顺序列表。
🎈总结遵循以下三条原则:
- 子类会先于父类被检查
- 多个父类会根据他们在列表中的顺序被检查
- 如果对下一个类存在两个合法的选择,选择第一个父类
新式类可以使用__mro__
查看继承列表
重写父类方法:
子类中使用super
调用父类方法来覆盖重写:
class Dad(metaclass=abc.ABCMeta):
def __init__(self, name):
self.name = name
class Son(Dad):
def __init__(self, name, age):
# Dad.__init__(self, name)
super().__init__(name)
self.age = age
result = Son("bill", 12)
特性2 多态:
运行时绑定状态
特性3 封装:
约定:
- 使用
_
来封装属性为私有属性:_age = 10
- 使用
__
开头的属性,Python会对其自动改名为_class__x
:__age
->__class_age
使用双下划线声明的属性,在继承给子类的时候,子类是无法覆盖的,原因就是python自动重命名了