"""
  day14 复习

  面向对象三大特征
    封装:分而治之(将需求拆解为多个类),封装变化(一个类表达一个变化点)
        需求:老王开车(坐地铁/开飞机/骑自行车)去东北.
        做法:定义人类/地铁类/飞机类/自行车类

    继承:抽象(代表)变化点,隔离用与做.
        做法:定义交通工具类,代表变化点(地铁类/飞机类/自行车类,要继承交通工具类)

            人类需要调用交通工具,而不关心(调用)变化点.

    多态:调用父类,执行子类.
        做法:变化点重写交通工具的运输方法(实现具体运输)
             调用老王去东北的方法时,需要传递变化点(地铁对象/飞机对象..)

  面向对象六大原则
    开闭原则(目标):允许增加新功能,不能修改以前的代码.
    依赖倒置(手段):调用父类(抽象/大概念/稳定),而不是调用子类(具体/小概念/变化).
"""


# -----------------封装------------------------
# 调用实例成员,要使用对象地址(传入,自行创建).
class A:
  def __init__(self, a01):
    self.a01 = a01
    self.b_obj = B(30)

  def fun01(self, b):
    # 传入B类对象再调用fun02
    b.fun02()
    print(self.a01)

  def fun03(self):
    # 在构造函数中创建B类对象再调用fun02
    self.b_obj.fun02()
    print(self.a01)


class B:
  def __init__(self, b01):
    self.b01 = b01

  def fun02(self):
    print(self.b01)


# ------------------
a_instance = A(10)
b_instance = B(20)

a_instance.fun01(b_instance)
a_instance.fun03()


# -----------------继承-多态-----------------------
class C:
  def fun04(self):
    print("fun04")

  def fun06(self):
    print("C --- fun06")


def fun07(c):
  # 希望调用父类方法
  c.fun06()

# ---------
class D(C):
  def fun05(self):
    print("fun04")

  # 重写父类方法
  def fun06(self):
    print("D --- fun06")

# ---------
d01 = D()
# 可以直接使用父类方法
d01.fun04()
d01.fun05()
d01.fun06()  # 执行子类

# 实际传入的是子类对象  [多态]
fun07(d01)
