封装
封装其实是一种思想,将事物状态和功能装进一个容器,那么这个容器在python中就是类,由这个类产生的对象都拥有类的属性和功能
在面向对象的思想中,推崇将具有某些共同特征的事物归为一类,那么这些事物就可以看做是这个类的具象化对象,但是允许个体拥有不同的特征
例如:你和我都是人,都具有人的基本功能,那么我们就是人的对象,我和你的名字可以不一样,性别可以不一样,但本质上我们都是人类
在前面我们说到,类不是实实在在存在的,是一系列拥有相似属性和功能的事物的抽离。那么在定义类和类的属性、功能上实际就是把这些属性和功能封装进类里面,抽离相似属性和功能并把它们放到类里,这种思想就是封装
class Animal:
dog = “”
human = “”
...
def eat(self):
print("enting")
def sleep(self):
print("sleeping")
动物类封装进了dog、human等等属性,封装了eat、sleep等功能,这些都属于Animal类共有的一些属性和功能
继承
继承的概念源于对现实事物的模拟,在人类的概念中,人类下面还有女人、男人、小孩、大人等细分概念,那么女人就是人类的扩展,人类概念就是女人概念的爸爸,女人概念除了拥有人类的所有属性和功能外还多了一个属性就是性别,那么女人类和人类就有非常多的相同属性和功能,回到编程中,这些高度相似或者相同的属性和功能其实就是重复的代码,继承的出现就是为了避免重复写大量代码描述两个属性和功能高度重合的类。
例:
class human:
legs = 4
ear = 2
def eat (self):
pass
class women:
legs = 4
ear = 2
sex = “”
def eat (self):
pass
由human 和 women 类可以看出,他们有相同的属性legs、ear和相同的功能eat(),如果在代码里这么写代码将非常冗余,面向对象语言几乎都有继承的思想,如果用继承来表示上面的代码将会是:
class human:
legs = 4
ear = 2
def eat (self):
pass
class women(human):
sex = ""
这样的话human就是继承women,human就是women的父类,women就是human的子类,women既有自己的属性sex,也拥有父类的所有属性和功能。
具体实现和原理见:
多继承
在python中允许多继承关系,一个类可以同时继承多个类,这样它就拥有所有父类的属性和方法
在python2中,没有继承任何类的类被称为经典类,默认不继承任何类
在python3中,所有的类默认继承object,这种类被称为新式类
菱形继承
a继承b,c,b,c由同时继承d,那么继承关系就形成闭环,此时a拥有的功能和属性最多,d拥有的功能和属性最少
菱形继承会带来属性查找顺序的问题,比如a的属性name是继承而来的,但不知道是b,c,d哪一个的,此时就会有查找顺序,在python2和python中是不一样的
python2中,是以深度查找为基本原则,即a->b->d->c,一直查找到继承关系最深的那一层
python3中,是以广度查找为基本原则的,即a->b->c->d,先将分支都查找完,最后找最深的那一层
多态
由同一父类派生的不同子类对象都可以作为参数传递给某个函数去执行,并产生不同的结果,这种形态叫多态。
例:
class A:
def __init__(self,name):
self.name = name
class B(A):
pass
def pri_name(obj):
print(obj.name)
b1 = B("egon")
b2 = B("owen")
pri_name(b1)
pri_name(b2)
打印结果:
egon
owen
鸭子类型
两个不相干的两个类的对象可以将自身作为参数传给同一个函数去调用执行,这样的就是鸭子类型,在python里十分推崇鸭子类型,一个生物不知道它是不是鸭子,但它只要长得像鸭子,水里游泳像鸭子,那就认为它是鸭子
class A:
def __init__(self,name):
self.name = name
self.age = 18
class B:
def __init__(self,name):
self.name = name
self.sex = "female"
def pri_name(obj):
print(obj.name)
b1 = B("egon")
b2 = B("owen")
pri_name(b1)
pri_name(b2)
打印结果:
egon
owen