类的三大特性---多态,以及菱形继承问题

菱形继承问题

经典类

  • 没有继承object类的就是经典类,只有Python2中有经典类
  • Python2当中不会默认继承object类,需要自己手动添加

新式类

  • 只要继承了object类的就是新式类,Python3当中所有的类都是新式类
  • 在Python3中会默认继承object类
class Foo:
    pass

print(Foo.__bases__)
(<class 'object'>,)

菱形继承

  • 当继承格局为菱形时,经典类和新式类搜索某一个属性的顺序会不一样
  • 经典类
    • 深度优先
  • 新式类
    • 广度优先
  • 经典类:一条路走到黑,深度优先

  • 新式类:不找那个最后继承的同一个类,直接去找下一个父类,广度优先

class G(object):
    def test(self):
        print('from G')

class E(G):
    def test(self):
        print('from E')

class B(E):
    def test(self):
        print('from B')

class F(G):
    def test(self):
        print('from F')

class C(F):
    def test(self):
        print('from C')

class D(G):
    def test(self):
        print('from D')

class A(B, C, D):
    def test(self):
        print('from A')

a = A()
a.test()
from A -->B-->E-->C-->F-->D-->G--object

只是菱形继承,普通继承正常顺序找

大招

  • __mro__或者mro()
# for i in A.mro():
for i in A.__mro__:
    print(i)
<class '__main__.A'>
<class '__main__.B'>
<class '__main__.E'>
<class '__main__.C'>
<class '__main__.F'>
<class '__main__.D'>
<class '__main__.G'>
<class 'object'>

多态与多态性

多态

  • 多种状态,只要大家能继承同一种东西A,这些东西就是A的多态

  • 一个类所延伸的多种形态,比如动物分为人类,狗类

import abc

class Animal(metaclass=abc.ABCMeta):		# 不推荐使用,这种方式会报错
    def __init__(self, height, weight):
        self.height = height
        self.weight = weight
	
    @abc.abstractmethod			# 类似于装饰器,强制要求子类必须有这个方法,没有就报错
    def sleep(self):
        print(self, '睡觉')

    @abc.abstractmethod			# 只有符合我的条件,才能成为我的儿子
    def eat(self):
        print(self, '吃饭')

class People(Animal):
    def sleep(self):
        print('我在睡觉')

    def eat(self):
        print('我在吃饭')

class Dog(Animal):
    def sleep(self):
        print('我也在睡觉')

    def eat(self):
        print('我也在吃饭')

d = Dog(100, 80)
d.sleep()
d.eat()
我也在睡觉
我也在吃饭
class Foo(Animal):		# 只要符合我的要求,就是我的儿子
    def sleep(self):
        print('我会睡觉')
        
    def eat(self):
        print('我会吃饭')

多态性

  • 在继承的前提下,使用不同的子类,调用父类的同一个方法,产生不同的功能
class Animal:
    def talk(self):
        print('讲话')

class Cat(Animal):
    def talk(self):
        print('miao~')
        
class Dog(Animal):
    def talk(self):
        print('wang~')

# Python(动态语言)
def func(obj):		# 不关心obj是什么
    obj.talk()

c1 = cat()
func(c1)

# 静态语言
def func(Cat, obj)		# 如果这里声明Cat,那就不能用Dog
def func(dog, obj)		# 同理,声明dog不能用cat
def func(Animal,obj)	# 声明animal就都可以用

多态在Python中的体现

鸭子类型(重要)

  • 动态类型的一种风格

  • 只要一个对象会走,会游泳,会叫,那么它就可以当成是一个鸭子处理

    对于我们这个例子:你只要有sleep方法/有eat方法,无论你怎么定义这个类,你就是动物的一种形态,你这样才能用动物的方法,否则无法使用动物的方法

结论

  • 所以在Python当中,没有真正意义上的多态,也不需要多态
原文地址:https://www.cnblogs.com/lucky75/p/11055066.html