首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python3面向对象-继承与多态

1:继承与多态介绍

继承:主要用于复用以前的代码,缩短开发周期。

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。

把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

2:继承与多态示例代码

# encoding=gbk class Animal: AnimalType = 'Animal' # 类属性 def __init__(self,name='Animal'): self.name = name def showInfo(self): # self 是具体的实例对象,type(self) 返回self对应的类(Animal或Animal的子类), print('类型:' + type(self).AnimalType + ' 名称:' + self.name) def eat(self): print('in Animal-吃吃吃!') class Dog(Animal): # 继承自Animal,具有Animal的属性和方法,当然其继承的属性和方法还在Animal的命名空间; AnimalType = 'Dog' # 此处的赋值不会影响父类中的AnimalType。给谁赋值就会在谁的命名空间创建一个新对象(当对象不存在时) def __init__(self,name = 'Dog',age = 3): Animal.__init__(self,name) # 调用父类的初始化函数,name存在于实例的命名空间中 # super().__init__(name) # 也可以通过使用 super() 来调用父类的方法 self.age = age # 给子类的实例添加新的属性 def eat(self): print('in Dog-吃吃!') class Tiger(Animal): AnimalType = 'Tiger' def __init__(self, name='Tiger'): # Animal.__init__(self, name) # super().__init__( name) # def eat(self): print('in Tiger-吃!') print('1:类中的属性与方法:'+'*'*60)print(Animal.__dict__)print(Dog.__dict__)print(Tiger.__dict__) animal = Animal('小动物')dog = Dog('小狗狗')tiger = Tiger('小老虎') print('2:实例中的属性与方法:'+'*'*60)print(animal.__dict__)print(dog.__dict__)print(tiger.__dict__) print('3:实例的方法调用:'+'*'*60)animal.eat()animal.showInfo()print('*'*25)dog.eat()dog.showInfo()print('*'*25)tiger.eat()tiger.showInfo()print('*'*25) print('4:多态:'+'*'*60) """喂养动物: 不需要知道是何种类型的动物,只要是继承自Animal的即可, 不够是现在已有的子类还是将来新增加的子类,下面的类都是 可用的。"""class Breeder: def feed(self,animal): # animal.eat() animal.showInfo() bd = Breeder()lst = []lst.append(dog)lst.append(animal)lst.append(tiger)for an in lst: bd.feed(an)

3:多继承

python中支持多继承,即子类可以继承多个父类的属性和方法。python中使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承,也叫菱形继承问题)等

MRO即method resolution order,用于判断子类调用的属性来自于哪个父类。在Python3中使用C3算法,采用广度优先搜索。

在Pythop中,对属性的引用以及方法的调用都会按照MRO的顺序来确定其属于哪个类中;对属性的赋值都会在其对应的类或实例中创建属性,与MRO无关。

示例代码:

# encoding=gbk class Base: def func(self): print('in Base - func ') def func2(self): print('in Base - func2 ') class A(Base): def func(self): print('in A - func ') class B(Base): def func(self): print('in B - func ') def func2(self): print('in B - func2 ') class C(A,B,Base): def func(self): print('in C - func ') class D(C): pass print(D.mro()) d = D()d.func()d.func2() # 按照MRO的顺序找func2,会在类B中找到 """输出:[, , , , , ]in C - func in B - func2 """

4:内置函数super()

4.1:初始化中使用super()

在Python中super()表示其父类,在初始化中会按照MRO的顺序分别调用父类的初始化函数,示例如下:

# encoding=gbk class Base: def __init__(self,val): print('init--Base') self.val = val def func(self): print('in Base - func ') def func2(self): print('in Base - func2 ') class A(Base): def __init__(self,val): print('init--A') super().__init__(val) # super(A,self).__init__(val) self.val += 2 def func(self): print('in A - func ') class B(Base): def __init__(self,val): print('init--B') super().__init__(val) # super(B,self).__init__(val) self.val += 3 def func(self): print('in B - func ') def func2(self): print('in B - func2 ') class C(A,B,Base): def __init__(self,val): print('init--C') super().__init__(val) # super(C,self).__init__(val) self.val += 4 def func(self): print('in C - func ') class D(C): pass print(D.mro()) d = D(0)print('1:'+'*'*30)d.func()print('2:'+'*'*30)d.func2() """输出:[, , , , , ]init--Cinit--Ainit--Binit--Base1:******************************in C - func 2:******************************in B - func2 """

4.2:方法调用中使用super()

按照MRO的顺序调用第一个找到的方法:

# encoding=gbk class Base: def func(self): print('in Base - func ') def func2(self): print('in Base - func2 ') class A(Base): def func(self): print('in A - func ') class B(Base): def func(self): print('in B - func ') def func2(self): print('in B - func2 ') class C(A,B,Base): def func(self): print('in C - func ') class D(C): def func(self): super().func() def func2(self): super().func2() print(D.mro()) d = D()d.func()d.func2()"""输出结果:[, , , , , ]in C - func in B - func2 """

4.3:运行时修改其父类

# encoding=gbk class X: def func(self): print('X.func') class Y: def func(self): print('Y.func') class Z(X): def func(self): # X.func(self) # 这样写,下面的改变基类操作将会不起作用, super().func() z = Z()print(Z.__bases__ )z.func() Z.__bases__ = (Y,) # 修改其父类为Yprint(Z.__bases__ )z.func() """输出:(,)X.func(,)Y.func"""

5:Python3中的抽象基类

抽象基类:即不能实例化的类。

在Python3中带有抽象方法的类就是抽象基类,其子类必须实现抽象方法。

# encoding=gbkfrom abc import ABCMeta,abstractmethod class Base(metaclass=ABCMeta): def delegate(self): self.func() @abstractmethod def func(self): pass # b = Base() #TypeError: Can't instantiate abstract class Base with abstract methods func class Sub(Base): def func(self): print('in Sub --func') s = Sub()s.delegate() # 首先调用父类中的方法delegate(),delegate()方法这依据self(即子类的实例)调用func """输出:in Sub --func"""

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200807A0C69G00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券