本文共 3170 字,大约阅读时间需要 10 分钟。
设计模式-里氏替换原则
面向对象的语言继承必不可少的,有如下优点
里氏替换原则,为继承定义规范。
正方形是一种特殊的长方形,如果将正方形设计为长方形的子类,不符合里氏替换原则
下方有三个类类图如下关系如上所示package demo1;public class SmartTest { /* * 长方形的长增加超过宽 * * @param r * */ public void resize(Rectangle r) { while (r.getHeight() <= r.getWidth()) { r.setHeight(r.getHeight() + 1); } }}
package demo1;/* * 定义一个长方形类 * @author ming * */public class Rectangle { protected long width; // 可以访问基类继承而来的,不能访问基类本身的,对同包内的可见,并且子类也可见 protected long height; public void setWidth(long width) { this.width = width; } public long getWidth() { return this.width; } public void setHeight(long height) { this.height = height; } public long getHeight() { return this.height; }}
package demo1;/* * 定义一个正方形类继承自长方形类 * * @author ming * * */public class Square extends Rectangle{ public void setWidth(long width, long height) { this.width = width; this.height = height; } public long getWidth() { return width; } public void setHeight(long height, long width) { this.height = height; this.width = width; } public long getHeight() { return height; }}
在上面的三块代码中,当调用SmartTest类的resize方法的时候,如果传入的是父类,那么将会可以的,如果传入的是子类,正方形,那么将会不可以的。
即。上方的为长方形行,正方形不行。所以上面的栗子不符合里氏替换原则。解决方法,使用继承时,要遵守里氏替换原则,类B继承类A时,不要重写父类A的方法,也不能重载父类A的方法。如果代码更改如下更改让其两个都共同定义同一个父类即可其中最上层的类为两个类的抽象类。
package com.ming;/* * 定义一个四边形类,只有get方法set方法 * @author ming * */public abstract class Quadrangle { protected abstract long getWidth(); protected abstract long getHeight();}
package com.ming;public class Rectangle extends Quadrangle { private long width; private long height; public void setWidth(long width) { this.width = width; } public long getWidth() { return this.width; } public void setHeight(long height) { this.height = height; } public long getHeight() { return this.height; }}
package com.ming;public class Square extends Quadrangle{ private long width; private long height; public void setWidth(long width) { this.height = width; this.width = width; } public long getWidth() { return this.,width; } public void setHeight(long height) { this.height = height; this.width = height; } public long getHeight() { return this.height; }}
在上方的图中,由于两个为平级关系,所以父类的地方,换成子类也都可以。
里氏替换原则;父类可以的地方,换成子类也同样可以。
一个栗子
package com.ming2;public class A { public int func1(int a, int b) { return a-b; }}
package com.ming2;public class B extends A{ public int func1(int a, int b) { return a+b; } public int func2(int a, int b) { return func1(a,b)+100; // 调用func1 }}
在上方中,如果这样书写
package com.ming2;public class Client { public static void main(String[] args) { B b = new B(); System.out.println(b.func1(100, 50)); }}
就违反了里氏替换原则,即子类能使用的时候,父类也必须能使用。
www.iming.info
转载地址:http://klvta.baihongyu.com/