(最早是由麻省理工学院的一位女士体提出)
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());
}
}
注:个人学习随记!