媒体报道

首页-天美娱乐-天美平台擎天联合【天美娱乐注册】擎天联合

2022-11-22 11:18:43 yqs888 0

首页-天美娱乐-天美平台擎天联合【天美娱乐注册】擎天联合报道,里氏替换原则(Liskov Substitution Principle, LSP)也叫里氏代换原则;里氏替换原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的。

定义一:

If S is a subtype of T, then objects of type T may be replaced with objects of type S, without breaking the program。

如果S是T的子类,则T的对象可以替换为S的对象,而不会破坏程序。

定义二:

Functions that use pointers of references to base classes must be able to use objects of derived classes without knowing it。

所有引用其父类对象方法的地方,都可以透明地替换为其子类对象。

1.2 里氏替换原则的两个含义:

  • 里氏替换原则是针对继承而言的,继承是为了实现代码重用,也就是为了共享方法,那么共享的父类方法就应该保持不变,不能被子类重新定义。子类只能通过新添加方法来扩展功能,父类和子类都可以实例化,而子类继承的方法和父类是一样的,父类调用方法的地方,子类也可以调用同一个继承得来的,逻辑和父类一致的方法,这时用子类对象将父类对象替换掉时,因为逻辑一致,所以相安无事。

  • 如果继承的目的是为了多态,而多态的前提就是子类覆盖并重新定义父类的方法,为了符合LSP,我们应该将父类定义为抽象类,并定义抽象方法,让子类重新定义这些方法,当父类是抽象类时,父类就是不能实例化,所以也不存在可实例化的父类对象在程序里。也就不存在子类替换父类实例(根本不存在父类实例了)时逻辑不一致的可能。

不符合LSP的最常见的情况是,父类和子类都是可实例化的非抽象类,且父类的方法被子类重新定义,这一类的实现继承会造成父类和子类间的强耦合,也就是实际上并不相关的属性和方法牵强附会在一起,不利于程序扩展和维护。

二、里氏替换的目的

采用里氏替换原则就是为了减少继承带来的缺点,增强程序的健壮性,版本升级时也可以保持良好的兼容性。即使增加子类,原有的子类也可以继续运行。

三、里式替换原则与继承多态之间的关系

里式替换原则和继承多态有关系, 但是他俩并不是一回事. 我们来看看下面的案例

public class Cache {    public void set(String key, String value) {      }
}public class Redis extends Cache {     @Override    public void set(String key, String value) {      }
}public class Memcache extends Cache {     @Override    public void set(String key, String value) {      }
}public class CacheTest {    public static void main(String[] args) {        // 父类对象都可以接收子类对象         Cache cache = new Cache();         cache.set("key123", "key123");          cache = new Redis();         cache.set("key123", "key123");          cache = new Memcache();         cache.set("key123", "key123");     }
}
复制代码

通过上面的例子, 可以看出Cache是父类, Redis 和 Memcache是子类, 他们继承自Cache. 这是继承和多态的思想. 而且这两个子类目前为止也都符合里式替换原则.可以替换父类出现的任何位置,并且原来代码的逻辑行为不变且正确性也没有被破坏。

看最后的CacheTest类, 我们使用父类的cache可以接收任何一种类型的缓存对象, 包括父类和子类。


首页
产品
新闻
联系