第一章 里氏替换原则

里氏替换原则: 所有引用基类的地方必须能透明的使用其子类的对象,简称LSP

我的理解:

子类必须比超类更加强大 并完全实现超类,

如果超类对某个方法已经有了自己的定义,确保调度的是超类方法(保证方法执行一致,多态在这里可能导致结果不一致,对于 接口,抽象类,不会产生这样的情况,因为它们不可实例化)(普通类继承的危险性)

注意:

1.在类调用其它类的时候务必使用超类或者接口,如果不能调用,则说明类的设计已经违背了lSP原则(ps:这话的意思我赞同,但放在这里感觉不协调,LSP原则只是说明子类可以完全代替超类,和是否使用多态没有太大的关系)

2.如果子类发生变形(如玩具枪和射杀枪),那么建议脱离继承,采用依赖、聚集、组合方式实现

这里有一个比较有意思的话题:

public class Father {
	public void doSomethin(HashMap hashMap) {
		System.out.println("超类执行了.....");
	}
}
public class Son extends Father{

	public void doSomething(Map map) {
		System.out.println("子类执行了.....");
	}
}

public class _Test {
	public static void main(String[] args) {
		Father some = new Father();
		some.doSomethin(new HashMap<>());
	}
}

public class _Test {
	public static void main(String[] args) {
		Father some = new Son();
		some.doSomethin(new HashMap<>());
	}
}

上面的类之间关系为了实现LSP,采用了投机取巧的办法,从作者的观点上来看,这是可行的,doSomething只是重载关系,只要你会传的是HashMap 子类的doSomething 永远不会被调用,从而保证方法调用 的一致性,但是这种关系实际上问题很多

  1. 子类方法doSometiong定义是可以处理任何Map的,但是它确没有办法处理HaspMap,会直接被超类的doSometiong覆盖掉,产生了逻辑上的混乱
  2. 代码的可读性极差,这也是为什么effective java 作者强烈建议使用@Override了,这种方法如果不仔细看,会直接以为是重写,父子类相同方法本就应该重写
  3. 可用性很差,没有可读性,没有可以维护性,除了非常特殊的情况下,不太可能使用这样的设计

设计标准:子类在实现继承的时候,应该尽量避免扩展,因为这样在多态使用的时候,子类的个性就会被抹杀:如果特地使用子类,就失去了多态的优势,使类的复用性降低


自己总结 :LSP原则:子类不要修改父类已经成型的方法(尽可能使用接口和抽象类,不可实例化为lsp提供了保障),确保子类超类调用同一方法的一致性(这种情况在维护超类出现同一方法的时候显得无可奈何),继承中可以扩展但尽量不要扩展

结论:少用继承,组合具有更好的解藕性

你可能感兴趣的:(Design,pattern)