python面向对象 : 继承
一. 初识继承
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类.
当我们在定义多个类的时候,发现要用到相同的方法或变量,如果每个类都要写相同的方法和变量,那么代码就会重复,为了减少代码,可以用继承来解决.
# 三个类中都有相同的参数,造成代码重复 class Person: def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age class Cat: def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age class Dog: def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age
用继承的思想来做
class Animal: animal = '动物' def __init__(self, name, sex, age): self.name = name self.sex = sex self.age = age def hobby(self): print('%s喜欢吃' % self.name) class Person(Animal): #继承Animal类 pass class Cat(Animal): pass class Dog(Animal): pass print(Person.animal) #动物 类名可以访问父类所有内容 p = Person('jack', '男', 25) p.hobby() #jack喜欢吃 # 子类以及子类实例化的对象 可以访问父类的任何方法或变量.先从本类中找hobby方法,找不到则从父类里找
既要执行子类的方法,又要执行父类的方法? 有两种解决方法.
1,Animal.__init__(self, name, sex, age)
2,super().__init__(name,sex,age)
class Animal: def __init__(self, name, sex, age): self.name = name self.sex = sex self.age = age def eat(self): print('%s会吃' % self.name) def drink(self): print('%s会喝' % self.name) class Bird(Animal): def __init__(self, name, sex, age, wing): # super().__init__(name, sex, age ) #自动把self传给父类 Animal.__init__(self, name, sex, age) self.wing = wing def egg(self): print('鸡会下蛋') def eat(self): #本类含有和弗雷相同的方法名 super().drink() #用super()调用父类的方法 print('鸟会吃虫子') b = Bird('鸟', '公', 30, '翅膀') print(b.__dict__) # {'name': '鸟', 'sex': '公', 'age': 30, 'wing': '翅膀'} b.eat() # 鸟会喝 #执行父类的eat方法 # 鸟会吃虫子 #执行本类的eat方法
二. 继承的进阶
1. 单继承和多继承
class A: pass class B(A): #单继承 pass class C(A): pass class D(B,C): #多继承 pass
2. 经典类, 新式类
新式类: 凡是继承object类都是新式类. python3x 所有的类都是新式类,因为python3x中的类都默认继承object.
经典类: 不继承object类都是经典类, python2x:(既有新式类,又有经典类) 所有的类默认都不继承object类,所有的类默认都是经典类.你可以让其继承 object.
单继承: 新式类,经典类查询顺序一样.
多继承继承顺序(讨论的是继承两个类):
新式类: 遵循广度优先 : 一条路走到倒数第二级,判断,如果其他路能走到终点,则返回走另一条路.如果不能,则走到终点. 可以用mro()来查询继承顺序.
经典类: 遵循深度优先 : 一条路走到底.
class A: def func(self): print('IN A') class B(A): # pass def func(self): print('IN B') class C(A): # pass def func(self): print('IN C') class D(B): # pass def func(self): print('IN D') class E(C): def func(self): print('IN E') class F(D,E): # pass def func(self): print('IN F') f1 = F() f1.func() #IN F print(F.mro()) # 查询类的继承顺序 # [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, # <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
3. 多继承原理: MRO_C算法
mro(): 查询类的继承顺序. 代码和步骤如下:
class H: pass class G(H): pass class F(H): pass class E(G): pass class D(F): pass class C(E): pass class B(D): pass class A(B, C, D): pass print(A.mro()) ''' 首先找到A继承的三个类的深度继承顺序,放到一个列表中 B [B,D,F,H] C [C,E,G,H] D [D,F,H] 每个列表的第一个元素为头部,其它位置元素都为尾部,从第一个列表的头部开始找,找其他列表中尾部是否含有 这个类名,如果没有,提取出来放到一个列表中,如果有,找下一个列表的头部,循环下去 只要提取来一个,我们就从第一个列表的头部接着重复上面的操作. A [A][B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D] A #找到第一个列表的头A,其他列表尾部没有A,把A取出来,如果其他列表的头部有A则剔除 [][B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D] B [][D,F,H] [C,E,G,H] [D,F,H] [C,D] C [][D,F,H] [E,G,H] [D,F,H] [D] D [][F,H] [E,G,H] [F,H] [] F [][H] [E,G,H] [H] [] E #找到第一个列表的头部H,但是其他列表尾部有H,所以跳过这个列表,去下一个列表取头部 [][H] [G,H] [H] [] G [][H] [H] [H] [] H [][] [] [] [] lst = [A,B,C,D,F,E,G,H] '''
class F: pass class E: pass class D: pass class C(D, F): pass class B(E, D): pass class A(B, C): pass print(A.mro()) ''' 首先找到A继承的两个类的深度继承顺序 把B作为子类,找出B类的查询顺序 B [B] [E] [D] [E,D] B [] [E] [D] [E,D] E [] [] [D] [D] D [] [] [] [] lst = [B,E,D] 把C作为子类,找出C类的查询顺序 C [C] [D] [F] [D,F] C [] [D] [F] [D,F] D [] [] [F] [F] F [] [] [] [] lst = [C,D,F] A [A] [B,E,D] [C,D,F] [B,C] A [] [B,E,D] [C,D,F] [B,C] B [] [E,D] [C,D,F] [C] E [] [D] [C,D,F] [C] C [] [D] [D,F] [] D [] [] [F] [] F [] [] [] [] lSt = [A,B,E,C,D,F] '''
无限的我,现在才开始绽放,从东边的第一缕阳光到西边的尽头