Java设计模式六大原则(2):里氏替换原则

(最早是由麻省理工学院的一位女士体提出)

1.定义:

(1)对于每一个类型为T1的对象o1,当使用类型为T2的对象o2对其进行替换时,对于所有的使用对象o1的程序段都没有影响。则说明类型T2时类型T1的子类。

 (2)所有引用基类的地方必须能透明的使用其子类的对象。

 (3)子类可以扩展父类的功能,但是不能改变父类原有的功能。

2.问题:有一个功能P1,由类A来完成实现。现在需要将功能P1进行扩展,扩展后的功能为P,此时的P由原有的功能P1以及新的功能P2组成。新的功能由类A的子类B来完成,则子类B在完成新的功能P2时,可能会导致原有的功能P1发生故障。

3.解决:在添加新的功能的同时,遵循里氏替换的原则,当B继承A时,除了添加新的功能P2外,尽可能的不要重写父类A的方法,也尽可能的不要重载父类 A的方法。

4.包含的4层含义:

(1).子类可以实现父类的抽象方法,但是尽可能不覆盖父类的非抽象方法。

(2).子类中可以增加自己特有的方法。

(3).当子类覆盖或者实现父类的方法的时候,方法的参数应该比父类更加的宽松。

(4).当子类覆盖或者实现父类的方法的时候,方法的返回值应该比父类更加的严格。

5.示例:

public class C {
    public int func(int a, int b){
        return a+b;
    }
}
 
public class C1 extends C{
    @Override
    public int func(int a, int b) {
        return a-b;
    }
}
 
public class Client{
    public static void main(String[] args) {
        C c = new C1();
        System.out.println("2+1=" + c.func(2, 1));
    }
}

此时的结果为2+1=1。显然不对,应该增加一个方法

public class C {
    public int func(int a, int b){
        return a+b;
    }
}
 
public class C1 extends C{
    public int func2(int a, int b) {
        return a-b;
    }
}
 
public class Client{
    public static void main(String[] args) {
        C1 c = new C1();
        System.out.println("2-1=" + c.func2(2, 1));
    }
}

此时结果:2-1=1

当子类覆盖或实现父类的方法时,方法的参数要比父类方法的输入参数更宽松

import java.util.HashMap;
public class Father {
    public void func(HashMap m){
        System.out.println("执行父类...");
    }
}
 
import java.util.Map;
public class Son extends Father{
    public void func(Map m){//方法的形参比父类的更宽松
        System.out.println("执行子类...");
    }
}
 
import java.util.HashMap;
public class Client{
    public static void main(String[] args) {
        Father f = new Son();//引用基类的地方能透明地使用其子类的对象。
        HashMap h = new HashMap();
        f.func(h);
    }
}

运行结果:执行父类...

  注意Son类的func方法前面是不能加@Override注解的,否则会编译提示报错,因为这并不是重写(Override),而是重载(Overload),因为方法的输入参数不同。

当子类的方法实现父类的抽象方法时,方法的返回值要比父类更严格

import java.util.Map;
public abstract class Father {
    public abstract Map func();
}
 
import java.util.HashMap;
public class Son extends Father{
     
    @Override
    public HashMap func(){//方法的返回值比父类的更严格
        HashMap h = new HashMap();
        h.put("h", "执行子类...");
        return h;
    }
}
 
public class Client{
    public static void main(String[] args) {
        Father f = new Son();//引用基类的地方能透明地使用其子类的对象。
        System.out.println(f.func());
    }
}

注:个人学习随记!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值