面向对象编程的三大特性分别是继承,封装和多态.
1.继承
继承是指在原有类的基础上创建新的类,新的类可以有自己特有的功能,也可以继承父类的功能.
继承可以很方便的复用已有的代码,大大减少重复的代码量.
python是支持多继承的.
1.1父类与子类
父类又被称为基类,超类;子类又被称为派生类.
子类中有一个类指针指向父类,会继承父类中的属性/方法,如果子类中有与父类中相同名称的属性/方法,则会优先调用子类中
的,可以通过父类名.属性/方法(self)或super().属性/方法()来使用.
父类并不能调用子类中的属性/方法.
除了自父类继承的属性/方法外,其他的属性/方法被称为派生属性/派生方法.
1.2经典类与新式类
python2中存在经典类和新式类,新式类是继承object类的类.
python3中所有的类都是新式类,默认继承object类.
经典类继承顺序遵循深度优先的算法,不能使用super内置函数.
新式类继承顺序遵循广度优先的C3算法,能够使用super内置函数.
需要注意的是在对python2的新式类使用super是必须要传递参数,而在python3中不必传参
1.3抽象类
抽象类是用来规范子类的一种类,抽象类不能被实例化.
通过导入abc(abstract base class)模块中的ABCMeta和abstractmethod来实现抽象类的功能.
from abc import ABCMeta,abstractmethod
class Cls(metaclass = ABCMeta):
@abstractmethod
def func(self):pass
以上的Cls类就是一个抽象类,所有Cls的子类中都必须有Func这个方法才能被实例化,否则在实例化时就会报错。
所谓的接口类:python中并无接口的概念,所以如果python中一个抽象类被多个继承,就可以称其中的抽象类为接口类.
2.封装
广义上的封装:那相同事物的属性和行为归到一个类中.
狭义上的封装:把一些属性和方法私有化,使其只能在类内部调用,不暴露给外部.
这里主要指的是狭义上的封装.
2.1属性/方法的私有化
通过在属性/方法名前加上双下划线来实现属性/方法的私有化,只能在类的内部被使用.
实际上只是将变量名改为_类名__属性/方法名,在内部时,加双下划线自动会找到私有的属性/方法,在外部可以通过这种方式在外部使用,但不应该这样使用.
在python中使用私有化相对比较少.
2.2封装的用途
对于类属性:不希望类属性直接暴露给外部使用.
对于方法:不希望被外部直接调用.
对于对象属性:不希望对象属性暴露给外部使用或者希望通过设置一个set方法来按照一定格式来进行修改.
2.3私有化属性/方法的继承
私有化属性不能被子类继承,因为私有化属性的原本的名字是_类名__属性名,但父类中不会有这个属性,父类用的是父类的类名,子类用的是子类中的类名,会提示属性不存在.
3.多态
定义:一个类具有多种状态
python是一门自带多态的语言,python中处处都是多态.
这个概念在python中体现的并不明显,在python中并不需要声明变量类型来传递一个参数.
3.1鸭子类型
鸭子类型是python中特有的
定义:只要一个东西长得像鸭子,行为像鸭子,那么他就是鸭子.
例如:能带人跑的都是交通工具,关注点就只在能带人跑这一点上,具体这个交通工具长什么样,是飞机还是轮椅,不关心.
对于len()内置函数来说,除了数字的基本数据类型都是鸭子,因为除了数字,内部都有__len__方法.
3.2归一化设计
归一化设计是python中多态的一种体现.
例如:
class Dog(object):
def play(self):
print('play with bone')
class Cat(object):
def play(self):
print('play with ball')
def play(animal):
animal.play()
将不同类中的相同功能相同名称的方法通过一个函数来使用,降低了使用的难度.