python-面向对象-继承
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类
继承可以分为单继承和多继承
单继承
class Animal(object):
def __init__(self, name, kind):
self.name = name
self.kind = kind
def eat(self, food):
print('%s eat %s' % (self.name, food))
class Cat(Animal): pass # 继承于Animal
class Dog(Animal): pass # 继承于Animal
hua = Cat('小花', '橘猫')
print(hua)
print(hua.name)
print(hua.kind)
hua.eat('小鱼干')
hei = Dog('小黑', '中华田园犬')
print(hei.name)
print(hei.kind)
hei.eat('单身狗粮')
可以查看继承关系(__bases__)
print(Cat.__bases__) # (<class '__main__.Animal'>,)
print(Dog.__bases__) #(<class '__main__.Animal'>,)
class Test: pass
print(Test.__bases__) # (<class 'object'>,) #如果没有指定基类,在继承Object
派生类
当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了.
class Animal(object):
def __init__(self, name, kind):
self.name = name
self.kind = kind
def eat(self, food):
print('%s eat %s' % (self.name, food))
def drink(self):
print('%s drink water' % (self.name))
def catch(self):
print('%s catch mouse' % (self.name))
class Cat(Animal):
def __init__(self, name, kind, eyes_color):
self.eyes_color = eyes_color # 派生属性
# super(Cat,self).__init__(name,kind)
super().__init__(name, kind) # 相当于执行父类的init方法
# Animal.__init(self,name,kind)
def climb(self): # 派生方法
print('%s climb tree' % self.name)
class Dog(Animal):
def chai(self):
print('%s cha' % (self.name))
hua = Cat('小花', '橘猫', '蓝色')
hua.eat('小鱼干')
hua.climb()
- 子类的对象,想使用某个名字,如何自己有,则使用自己的,若自己没有,用自己父类,如果父类的都没有,则报错
- 既想使用子类的,也想使用父类的,那就在子类的方法中使用
- 父类名.方法名(self,参数1,参数2)
- super().方法名(参数1,参数2)
在python3当中,所有的类都继承object类,所有的类都是新式类
所有的类的类祖宗 都是object
父类是object的类 —— 新式类
多继承
'''
各种动物,每一种动物都是一个类
青蛙、天鹅、老虎、鹦鹉
青蛙 :走,游泳
天鹅 :走,游泳,飞
老虎 :走,游泳
鹦鹉 :走,飞,说话
'''
class FlyAnimal:
def fly(self):pass
class SwimAnimal:
def swim(self):pass
def eat():pass
class WalkAnimal:
def walk(self):pass
def eat():pass
class Frog(SwimAnimal,WalkAnimal): pass # 多继承
class Tiger(SwimAnimal,WalkAnimal):pass# 多继承
class Swan(FlyAnimal,SwimAnimal,WalkAnimal):pass # 多继承
class Parrot(FlyAnimal,WalkAnimal):# 多继承
def talk(self):
pass
多继承 是python语言中特有的继承方式
java语言中不支持多继承的,C#也不支持多继承
C++支持多继承
# 多继承和单继承是一样的
# 如果对象使用名字
# 是子类中有的,那么一定用子类的
# 子类没有,可以到多个父类中去寻找
那如果多个和父类都有,那么用谁的??
python的继承了多个类,其寻找的方式有两种,分别是深度优先,广度优先
- 当类是经典类的时候,是按照深度优先进行查找
- 当类是新式类的时候,是按照广度优先进行查找
python2.x是默认是经典类,如果在类继承Object,则是新式类,在python3.x默认是新式类,默认继承Object
广度优先
class A(object):
def func(self):
print('a')
class B(A):
pass
# def func(self):
# print('b')
class C(A):
pass
# def func(self):
# print('c')
class D(B,C):
pass
# def func(self):
# print('d')
d = D()
d.func()
print(D.mro())
'''
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
'''
基于广度优先:
P1=[P1O]
P2=[P2O]
C1 =C1+[P1O]+[P2O]
C1 = [C1P1P2O]
C2=[C2P1P2O]
D = D+[C1P1P2O]+[C2P1P2O]
DC1 =[P1P2O]+[C2P1P2O]
DC1C2 =[P1P2O]+[P1P2O]
DC1C2P1 =[P2O]+[P2O]
DC1C2P1P2 =[O]+[O]
DC1C2P1P2O
D->C1->C2->P1->P2->O
基于深度优先:上述的图中 如果是深度优先的话,则不能继承Object,假设没有继承Object
class P1():pass
# def func(self):
# print("P1")
class P2():pass
# def func(self):
# print("P2")
class C1(P1, P2):pass
# def func(self):
# print("C1")
class C2(P1, P2):pass
# def func(self):
# print("C2")
class D(C1, C2):
pass
# def func(self):
# print("D")
d = D()
# d.func()
# D ->c1->P1->p2-C2
class A():pass
# def test(self):
# print('from A')
class B(A):
# def test(self):
# print('from B')
pass
class C(A):
def test(self):
print('from C')
class D(B):pass
# def test(self):
# print('from D')
class E(C):pass
# def test(self):
# print('from E')
class F(D,E):
# def test(self):
# print('from F')
pass
f1=F()
f1.test()
基于深度优先:# F->D->B-A-E-C
基于广度优先:#F->D->B->E->C->A