1、组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合。作用是可以将两个本来不相关的类联系起来。一般是两个类之间有显著的不同,很多时候还要附属关系。比如人和头,手机和电池等等
classMonster(object):def __init__(self,hp):
self.hp=hpclassWepon():
damage=10
classSuperman(object):def __init__(self,hp):
self.__hp=hp
self.damage=Wepon() #这就是组合defgongji(self,monster):
monster.hp-=self.damage.damageif __name__=='__main__':print(('游戏开始').center(30,'*'))print('怪兽产生了')
monster1=Monster(100)print('怪兽的血量是%d'%monster1.hp)
s1=Superman(100)print('产生了一个超人,攻击力是%d'%s1.damage.damage)
s1.gongji(monster1)print('怪兽受到攻击,血量变成%d'%monster1.hp)
2、当类之间有很多相同的功能时,可以把这些相同的功能封装成一个基类,这样就可以利用继承来实现代码的重用。
下面我们来看看第一种继承方式
defPeople():defeat():pass
defrun():pass
defStudent(People):defkaoshi():pass
其实这种继承意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。所以常常使用的是继承的第二种方法,它非常重要。它又叫“接口继承”。
接口继承: 要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。要导入abc模块
importabcclass People(metaclass=abc.ABCMeta):
@abc.abstractmethoddefeat(self):pass@abc.abstractmethoddefrun(self):pass
classStudent(People):defeat(self):print('学生正在饭堂吃饭')defrun(self):print('学生正在跑步')classTeacher(People):defeat(self):print('老师在吃饭')defrun(self):print('老师在跑步')
s1=Student()
s1.eat()
这样子写完的好处就是方便用户的使用,因为不管是老师对象还是学生对象都有基本的吃饭和跑步方法,不必去纠结这个类究竟有没有这个方法。
当出现多重继承的时候,我们要去调用一个方法时候,应该怎么去查找这个方法?搞明白这概念之前我们先来看看几个基本的概念。
Python2中:
经典类:class A:pass
新式类:class A(object):pass
在Python3中默认上面两种格式都是新式类。
广度优先:只要是新式类都是广度优先。Python3中全都是广度优先。如果有多个分支,不会直接查找到顶层。
深度优先:Python2中的经典类。直接查找到顶层。
所有的查找顺序都存放在一个名字为__mro__的元组中。调用一个方法本质上是在__mro__这个按顺序去查找
classA():deftest(self):print('A')classB(A):deftest(self):print('B')classC(A):deftest(self):print('C')classD(B):deftest(self):print('D')classE(C):deftest(self):print('E')classF(D,E):deftest(self):print('F')print(F.__mro__)#(, , , , , , )