继承与多态
一、继承
继承是一种创建新类的方式,在python中,新建的类可以继承一个或者多个父类,新建的类可以称为子类或者父类,被继承的类可以称为父类或者基类。
子类可以使用父类中的属性或者方法
解决了类与类之间代码冗余的问题
在python2当中,继承了object类的子子孙孙类都称为新式类,没有继承的都称为经典类
在python3中,没有区分经典类和新式类,都是新式类

单继承
只继承一个父类的被称为单继承
单继承下的属性查找
class Foo():
def f2(self):
print('from Foo')
def f1(self):
print('from Foo')
class Bar(Foo):
def f1(self):
print('from f1')
# 当该属性或方法在子类中,则使用子类的,如果没有则去父类中寻找,父类中也没有就会报错
obj = Bar()
obj.f1() # from f1
obj.f2() # from Foo
obj.f3() # 报错
# 练习1
class Foo: def f1(self): print('Foo.f1') def f2(self): # print('Foo.f2') self.f1() class Bar(Foo): def f1(self): print('Bar.f1') obj = Bar() # {} obj.f2()
# 练习2 class Foo: def __f1(self): # _Foo__f1() print('Foo.f1') def f2(self): # print('Foo.f2') self.__f1() # _Foo__f1() class Bar(Foo): def __f1(self): # # _Bar__f1() print('Bar.f1') obj = Bar() # {} obj.f2()

多继承
继承多个父类的被称为多继承
多继承下的属性查找
多继承下的属性查找一般分为按照广度查找和按照深度查找
新式类都是按照广度查找的
class G:
def test(self):
print('from A')
class E(G):
def test(self):
print('from B')
pass
class F(G):
def test(self):
print('from C')
pass
class B(E):
def test(self):
print('from D')
pass
class C(F):
def test(self):
print('from B')
pass
class D(G):
def test(self):
print('from B')
pass
class A(B,C,D): def test(self): print('from A') pass print(F.mro()) # 查找顺序 [<class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>] f1 = F() f1.test()

经典类都是按照深度查找顺序查找的
class G:
def test(self):
print('from A')
class E(G):
def test(self):
print('from B')
pass
class F(G):
def test(self):
print('from C')
pass
class B(E):
def test(self):
print('from D')
pass
class C(F):
def test(self):
print('from B')
pass
class D(G):
def test(self):
print('from B')
pass
class A(B,C,D): def test(self): print('from A') pass print(F.mro()) # 查找顺序 [<class '__main__.B'>, <class '__main__.E'>, <class '__main__.G'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class 'object'>] f1 = F() f1.test()

二、super()和mro列表的使用
super()应用
super()会返回一个特殊的对象,该对象会参考发起属性查找的那一个类的mro列表,依次去当前类的父类中查找属性。
mor列表
mro()会显示类的继承顺序,mor列表会按照从左到右开始查找父类,直到找到第一个匹配这个属性的类为止,类.mro()查看mro列表
class B:
def test(self):
print('B---->test')
def aaa(self):
print('B---->aaa')
class A:
def test(self):
print('A---->test')
super().test()
class C(A, B):
def aaa(self):
print('C----->aaa')
c = C()
c.test() # 打印结果: A---->test B---->test
print(C.mro())
三、多态与多态性
什么是多态
多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承)
例如动物的多种形态:人、狗、猪
# 多态:同一种事物的多种形态,动物分为人类,猪类(在定义角度)
# 方式1
class Animal:
def run(self):
raise Excecption('子类必须实现这个方法')
class People(Animal):
def run(self):
print('人正在走')
class Pig(Animal):
def run(self):
print('pig is walking')
class Dog(Animal):
def run(self):
print('dog is running')
peo = People()
pig = Pig()
d = Dog()
peo.run()
pig.run()
d.run()
# 方式2
import abc
class Animal(metaclass=abc.ABCMeta): # 同一类事物:动物
@abc.abstractmethod
def talk(self):
pass
class People(Animal): # 动物的形态之一:人
def talk(self):
print('say hello')
class Dog(Animal): # 动物的形态之二:狗
def talk(self):
print('say wangwang')
class Pig(Animal): # 动物的形态之三:猪
def talk(self):
print('say aoao')
什么是多态性
多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息,不同的对象在接收 时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。
#多态性:一种调用方式,不同的执行效果(多态性)
def func(obj):
obj.run()
func(peo1)
func(pig1)
func(d1)
# peo1.run()
# pig1.run()
# 多态性依赖于:继承
##多态性:定义统一的接口,
def func(obj): #obj这个参数没有类型限制,可以传入不同类型的值
obj.run() #调用的逻辑都一样,执行的结果却不一样
func(peo1)
func(pig1)
func(d1)
总结
多态:同一种事物的多种形态,动物分为人类,猪类(在定义角度) 多态性:一种调用方式,不同的执行效果(多态性)
三、为什么要用多态性(多态性的好处)
(1)增加了程序的灵活性
以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)
(2)增加了程序额可扩展性
通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用

浙公网安备 33010602011771号