类与类之间的关系是什么样子的?继承和组合。

  • 继承是 is-a 的关系,子类 is-a 父类
  • 组合是 has-a 的关系, 类B调用类A的方法,或调用模块

继承和组合的目的都是为了解决代码复用的问题。

继承和组合的使用场景是什么?或者说何种场景下选择继承或组合呢?

  1. 尽量不要使用多态继承。不是不可以使用继承,但要避免一个类继承了太多的类。

  2. 使用组合将代码打包,形成模块。这样模块可以反复使用。

  3. 组合优先,继承靠后。

  4. 不要被以上规则约束,尽量适应你团队里的习惯。

继承

继承就是子类继承父类的属性和方法,包括隐式继承,显式继承,super()

隐式继承

子类自动继承父类的方法

class Parent(object):
    count = 0

    def implicit(self):
        print("PARENT implicit()")
        Parent.count += 1
        print(Parent.count)

class Child(Parent):
    pass 

dad = Parent()
son = Child()

dad.implicit()
son.implicit()

# 结果如下,说明 Parent()的implicit()被调用了两次。
# PARENT implicit()
# 1
# PARENT implicit()
# 2

显示继承

当子类方法名和父类方法名相同时,优先使用子类方法。

class Parent(object):
    count = 0

    def override(self):
        print("PARENT override()")
        Parent.count += 1
        print(Parent.count)

class Child(Parent):
    
    def override(self):
        print("CHILD override()")

dad = Parent()
son = Child()

dad.override()
son.override()

# 结果如下,说明 Parent()的override()被调用了两次。

# PARENT override()
# 1
# CHILD override()

前后修改

在父类的版本运行之前或之后修改行为。先子类优先,使用super()调用父类。

super()解决了多重继承中寻找多个父类中的方法问题,多直接用在子类的__init()__中。

例子1

class Child(Parent):

    def __init(self, stuff):
        self.stuff = stuff
        super(Child, self).__init__()

例子2

class Parent(object):
    count = 0

    def altered(self):
        print("PARENT altered()")
        Parent.count += 1
        print(Parent.count)

class Child(Parent):
    
    def altered(self):
        print("CHILD BEFORE PARENT altered()")
        super(Child, self).altered()
        print("CHILD AFTER PARENT altered()")


dad = Parent()
son = Child()

dad.altered()
son.altered()

# 结果如下,说明PARENT altered()被调用了两次。
# PARENT altered()
# 1
# CHILD BEFORE PARENT altered()
# PARENT altered()
# 2
# CHILD AFTER PARENT altered() 

组合

组合也能实现继承的效果,通过将类A赋值给类B内的self,实现对类A里方法的调用。或者类B里使用模块。

class Other(object):
    
    def override(self):
        print("OTHER override()")

    def implicit(self):
        print("OTHER implicit()")

    def altered(self):
        print("OTHER altered()")

class Child(object):

    def __init__(self):
        self.other = Other()
    
    def implicit(self):
        self.other.implicit()

    def override(self):
        print("CHILD override()")
    
    def altered(self):
        print("CHILD BEFORE OTEHR altered()")
        self.other.override()
        print("CHILD AFTER OTHER altered()")


son = Child()

son.implicit()
son.override()
son.altered()

# 结果如下

# OTHER implicit()
# CHILD override()
# CHILD BEFORE OTEHR altered()
# OTHER override()
# CHILD AFTER OTHER altered()