创建个人网站教案,一级做ae视频直播可以吗多少钱,互联网保险发展现状,室内装饰设计师证什么是里氏替换原则#xff1a;只要父类能出现的地方子类就可以出现#xff0c;而且 替换为子类也不会产生任何错误或异常#xff0c;使用者可能根本就不需要知道是父类还是子类。但是#xff0c;反过来就不行了#xff0c;有子类出现的地方#xff0c;父类未必就能适应。…什么是里氏替换原则只要父类能出现的地方子类就可以出现而且 替换为子类也不会产生任何错误或异常使用者可能根本就不需要知道是父类还是子类。但是反过来就不行了有子类出现的地方父类未必就能适应。
简而言之子类在重写或重载父类的方法时对方法的返回值或输入参数应该是“小于等于”或更具体于父类的方法。这里的“小于等于”指的是继承关系中子类方法的行为不应该超出父类方法的行为范围。
为了更好地理解让我们来解释一下含义 覆写Override的情况 当子类覆写父类的方法时子类的方法应该具有相同的方法名、相同的输入参数但方法体可以重新实现。在这种情况下方法的返回值类型也称为方法的协变类型应该是父类方法返回值类型的子类型即小于等于父类返回值类型。这是为了确保子类的行为不会超过父类的行为范围。 重载Overload的情况 重载是指在同一个类中方法名相同但输入参数不同的情况。在继承关系中子类可以重载父类的方法但是子类重载的方法应该有更宽松的输入参数要求即子类的输入参数类型应该是父类的输入参数类型的父类型即宽于或等于父类输入参数类型。这是为了确保子类方法可以适用于更广泛的输入。
总结起来LSP要求子类覆写的方法不应该做超出父类方法行为范围的事情而子类重载的方法应该具有更广泛的输入参数要求。这样可以保证在使用子类对象替代父类对象时不会出现意外的行为同时保持了代码的可靠性和一致性。
总结一下
1、覆写是返回值的范围应该变小(确保行为范围)重载是入参的范围应该变大。
2、同时类的覆写和类的重载本身与返回值没有关系。 子类中方法的前置条 件必须与超类中被覆写的方法的前置条件相同或者更宽松
这句话在讲述里氏替换原则Liskov Substitution PrincipleLSP中的另一个关键概念即子类中覆写重写方法的前置条件preconditions与父类中被覆写方法的前置条件相比应该保持相同或者更宽松。
前置条件指的是方法执行前需要满足的一些条件以确保方法的正常执行。里氏替换原则要求 相同的前置条件 子类中覆写父类方法时子类方法的前置条件必须与父类方法的前置条件相同。这意味着在调用子类方法之前所需的条件和约束应该与调用父类方法时相同以确保代码的稳定性和可预测性。 更宽松的前置条件 子类方法的前置条件可以比父类方法更宽松。这是为了增强子类的灵活性和适用性。如果子类方法的前置条件比父类方法宽松那么意味着子类方法可以在更多的情况下被调用而不会破坏程序的正确性。
总之这一原则确保了子类的方法在被调用时能够满足至少与父类方法相同的前置条件以及更宽松的前置条件从而避免了在子类中破坏父类行为的情况。这有助于保持代码的合理性和可维护性。
demo
public class Father {public Collection doSomething(Map map) {System.out.println(父类被执行...);return map.values();}
}public class Son extends Father {//子类的范文更小所以最后没有满足 里氏替换原则public Collection doSomething(HashMap map) { System.out.println(子类被执行...);return map.values();}
}public class Client {public static void invoker() {Father f new Father();HashMap map new HashMap();f.doSomething(map);}public static void main(String[] args) {invoker(); //父类被执行...}
}public class Client {public static void invoker() {Son f new Son();HashMap map new HashMap();f.doSomething(map);}public static void main(String[] args) {invoker(); //子类被执行... 没有满足 里氏替换原则}
}