里氏替换原则
来源:互联网 发布:用php画环形统计图 编辑:程序博客网 时间:2024/06/08 10:28
里氏替换原则,主要是一个关于继承的规范原则,它要求我们在软件中写继承关系时,所有引用父类的地方必须能够
透明地使用其子类对象,子类可以实现父类所提供的抽象方法,但不要去重写父类已经实现的方法,或者重载父类的
构造。要维护继承的传递性,当然很多地方为这个原则打了个比喻为:“龙生龙,凤生凤,老鼠的儿子会打洞”
里氏替换原则,告诉我们,在软件中将一个父类对象替换成它的子类对象,程序将不会产生任何错误或异常的话,那
么这两个对象才具有继承关系,也就是IS-A关系。当然,反过来说,使用子类对象的地方却不一定都能使用其父类进
行替换,我相信这个应该很好理解,子类扩展的地方,父类就是没有办法实现的。
为了遵循里氏替换原则,我们在软件中通常有种写法,在程序中我们采用父类的基本类型来对对象进行定义,而在运
行时再确定其子类类型,目的就是用子类对象来替换父类对象,所以很多原则,实际上在我们平时写代码这个过程
中,就有了体现。
在使用里氏替换原则时,需要注意的事项有:
1、子类的所有方法必须要在父类中有所声明,或者换句话说,就是子类必须实现父类中声明的所有方法。为什
么要有这个事项呢?其实很好理解,我们在写程序时,经常用父类来声明对象定义,这样有助于保证系统的扩展性,
在运行时用子类对象来替换父类对象,那么如果一个方法只存在子类中,在父类中却不提供对应的声明,那么父类对
对象如何去使用这个方法呢?
2、我们在使用里氏替换原则时,尽量把父类设计成抽象类或接口,让子类继承或实现其方法,运行时,由子类
对象替换掉父类对象,这样提高我们程序的扩展性,如果需要扩展其他类,无须修改原有子类的代码,只需要其他子
类继承或实现对应的父类或父接口即可,里氏替换原则其实也是开闭原则的一种体现。
举个符合替换原则的例子:
父类中,我们提供了2个方法,一个eat(),例外一个是breathe(),breathe()是一个抽象方法,因为这是子类特有的扩
展方法,父类无须实现, 但需要声明。eat()在父类中已经有过实现,那么子类只需继承即可,而无须重写,确保继承
的连贯性,老鼠的儿子不能连洞都不会打了,改去追狗了……。
代码体现:
package yuanze;/** * 将父类声明为抽象类 * * @author Administrator * */public abstract class Super {/** * 定义一个父类无须实现的抽象方法 */public abstract void breathe();/** * 定义父类需要实现的方法 */public void eat() {System.out.println("我吃面");}}
子类:
package yuanze;/** * 定义子类继承父类 * * @author Administrator * */public class Child extends Super {/** * 子类扩展的方法,但是在父类中有声明 */@Overridepublic void breathe() {// TODO Auto-generated method stubSystem.out.println("呼吸");}}
客户端调用时:
package yuanze;public class Test {public static void main(String[] args) {Super c = new Child(); // 由子类的实例替代父类的实例c.eat();}}
执行后的结果是:
我吃面
也就是说:子类继承父类后,无论继承多少次,那么只要eat(),那么就一定得到的是“我吃面”。如果子类重写了父类
的eat()方法,那么就可能出现“我跟着老婆走,我吃大米了!”的情况了,那就违背了里氏替换原则。可以这样理解,
父类中凡是已经实现好方法,那就是需要你继承着走的,那都是设计的一系列的规范和契约,如果任意去修改,就有
可能对整个继承体系造成破坏。子类需要扩展的方法,一定要通知到自己的父类,也就是需要在父类中声明。
通俗的说,这个原则就是:子类可以扩展父类的功能,但不能改变父类原有的功能。
1、子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法(不能把Y基因变成了Z,O(∩_∩)O哈哈~)。
2、子类中可以增加自己特有的方法,但需要在父类中声明(要跟到老婆走,是不先要给父亲说些呢?)。
3、当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松,这个
从参数个数上考虑。
4、当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更加严格,如父类要
求返回List,那么子类就应该返回List的实现ArrayList,父类是采用泛型,那么子类则不能采用泛型,而是具体的返
回。
- 里氏替换原则
- LSP(里氏替换原则)
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- 里氏替换原则
- keil MDK启动文件分析---基于LPC2100系列
- 利用上下文信息
- csharp: DataRelation objects to represent a parent/child/Level relationship
- csharp: DataRelation objects to represent a parent/child/Level relationship
- 【BZOJ3143】[Hnoi2013]游走【高斯消元】【期望DP】【贪心】
- 里氏替换原则
- windows上安装Anaconda和python
- Android Drawable 那些不为人知的高效用法
- 基于权重的随机数JS实现
- Java程序中的“内存泄漏”问题
- Eclipse调试:F5、F6、F7、F8 (总要开个头吧)
- 深入了解cookie
- 《CSS入门经典》学习笔记
- java回顾