设计模式之设计原则学习(1):里氏替换原则

2018-03-01 11:07:33来源:oschina作者:昆卡爱吃鱼人点击

分享

自己总结的里氏替换原则的定义:一个使用基类A的地方,可以替换成基类A的子类,并且替换后程序的逻辑不会改变


例如:基类不是抽象类或者接口,可以实例化时,我们在编写这个基类的子类时,应该尽量避免重写基类中有实际逻辑的方法;以下是反例:


public class A{
public String getName(){
return "A";
};
};
public class B extends A{@Override
public String getName(){
return "B";
};
};
public class C{
public void test(A a){
// 这里代码只想调用a的getName()方法;实际工作中这个方法里还会有和a相关的逻辑
System.out.println("我的名字是:"+a.getName());
}
}
public class client{
public static void main(String[] args){
B b = new B();
C c = new C();
// 这个方法定义的形参类型是A,但是这里实际传入的是A的子类B的对象,结果调用的是B的getName()方法,这时候其他和a相关的逻辑可能就会出错
c.test(b);
}
};

运行结果: 我的名字是:B


程序实际的预计运行结果应该是:我的名字是:A


解决这个问题,我们需要定义一个A和B的共用抽象基类,并将getName()方法抽象,将C中的test方法中的参数类型改为A和B的抽象基类


public abstract class X{
public abstract String getName();
}
public class A extends X{
@Override
public String getName(){
return "A";
};
};
public class B extends X{@Override
public String getName(){
return "B";
};
};
public class C{
public void test(X x){
// 这里代码只想调用实现X类的getName方法;实际工作中会考虑到X会有多个子类
System.out.println("我的名字是:"+x.getName());
}
}
public class client{
public static void main(String[] args){
B b = new B();
C c = new C();
// 这个方法定义的形参类型是X,但是这里实际传入的是X的子类B的对象,结果调用的是B的getName()方法
c.test(b);
}
};

这时候A和B都继承了同一个抽象基类X,在C中的test方法中就会考虑到会有X的子类用不同的逻辑实现getName方法,test方法中的逻辑就不会因为传入形参的子类而出错了


最后总结一下里氏替换原则希望我们做的:


尽量继承抽象的基类,继承非抽象的基类时尽量避免重写基类已经具体实现的方法

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台