zchfeng / Front-End-note

1 stars 0 forks source link

里氏替换原则 #17

Open zchfeng opened 2 years ago

zchfeng commented 2 years ago

定义:所有引用基类的地方必须能透明地使用其子类的对象。子类可以扩展父类的功能,但不能改变父类原有的功能

1、子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法

class Father {
  sum(a, b) {
    console.log(a + b);
  }
}

class Son extends Father {
  sum(a, b) {
    console.log(a - b);
  }
}

class Client {
  main() {
    let father = new Father();
    father.sum(1, 2);

    // 父类存在的地方,可以用子类替代
    // 子类Son替代父类Father
    let son = new Son();
    son.sum(1, 2);
  }
}

new Client().main(); // 3  -1
zchfeng commented 2 years ago

2、子类中可以增加自己特有的方法

class Father {
  sum(a, b) {
    console.log(a + b);
  }
}

class Son extends Father {
  sub(a, b) {
    console.log(a - b);
  }
}

class Client {
  main() {
    let father = new Father();
    father.sum(1, 2);
    // 父类存在的地方,可以用子类替代
    // 子类Son替代父类Father
    let son = new Son();
    son.sum(1, 2);
    son.sub(1, 2);
  }
}

new Client().main(); // 3  3 -1
zchfeng commented 2 years ago

3 、当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松

class Father {
  sum(a, b) {
    console.log(a + b);
  }
}

class Son extends Father {
  sum(a, b) {
    if (arguments.length > 2) {
      this.__proto__.__proto__.fun(arguments[0], arguments[1]);
    } else {
      console.log(a - b);
    }
  }
}

class Client {
  main() {
    let father = new Father();
    father.sum(1, 2);

    // 父类存在的地方,可以用子类替代
    // 子类Son替代父类Father
    let son = new Son();
    son.sum(1, 2);
    son.sum(1, 2, 3);
  }
}

new Client().main(); // 3  -1  3
zchfeng commented 2 years ago

4、当子类的方法实现父类的(抽象)方法时,方法的后置条件(即方法的返回值)要比父类更严格

zchfeng commented 2 years ago

总结:

继承优点: 代码的共享 代码的重用 子类好像父类 提高代码的可开展性 提高产品和项目的开放性

缺点:继承有侵入性、降低了代码的灵活性、增加了耦合性

2、里氏替换原则:所以利用基类的地方必须能透明的使用其子类的对象(简单的说,子类可以替换父类,执行结果没有改变)

3、作用:用来是继承的优势(优点)更加明显,缺点更加少。

4、里氏替换的规范(主要的核心):

1)子类必须完成实现父类的方法 2)子类可以有自己的个性(自己的方法) 3) 覆盖或者实现父类的方法时,输入的参数范围,子类的范围大于父类 4)覆写或者实现父类的方法时,输出的结果,子类返回的小于或者等于父类的返回值