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