设计模式课程 设计模式精讲 3-10 里氏替换原则coding
1 代码演练
1.1 继承关系判别(是否是真正意义的继承)
1.2 入参控制
1.3 出参控制
1 代码演练
1.1 继承关系判别(是否是真正意义的继承)(其实我觉得这个例子有点牵强)
1.1.1 反例
结论:
确定继承关系的时候一定要判断好,是否父类的方法子类可以继承。传统意义的正方形是矩形的子类,在这里是不适用的。
测试类1:
package com.geely.design.principle.liskovSubstitutation;
public class TestSquare {
public static void resize(Rectangle rectangle){
while(rectangle.getWidth()<=rectangle.getLength()){
rectangle.setWidth(rectangle.getWidth()+1);
System.out.println("长为"+rectangle.getLength()+"****************宽为"+rectangle.getWidth());
}
}
public static void main(String [] args){
Rectangle rectangle = new Rectangle();
rectangle.setWidth(10);
rectangle.setLength(20);
resize(rectangle);
}
// public static void main(String [] args){
// Square square = new Square();
// square.setLength(10);
// resize(square);
// }
}
打印结果1:
"C:\Program Files\Java\jdk1.6.0_43\bin\java.exe" "-javaagent:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\lib\idea_rt.jar=17363:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.6.0_43\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\rt.jar;F:\xiangmu3\Xin\Idea\out\production\design_pattern" com.geely.design.principle.liskovSubstitutation.TestSquare
长为20****************宽为11
长为20****************宽为12
长为20****************宽为13
长为20****************宽为14
长为20****************宽为15
长为20****************宽为16
长为20****************宽为17
长为20****************宽为18
长为20****************宽为19
长为20****************宽为20
长为20****************宽为21 Process finished with exit code 0
测试类2:
package com.geely.design.principle.liskovSubstitutation;
public class TestSquare {
public static void resize(Rectangle rectangle){
while(rectangle.getWidth()<=rectangle.getLength()){
rectangle.setWidth(rectangle.getWidth()+1);
System.out.println("长为"+rectangle.getLength()+"****************宽为"+rectangle.getWidth());
}
}
// public static void main(String [] args){
// Rectangle rectangle = new Rectangle();
// rectangle.setWidth(10);
// rectangle.setLength(20);
// resize(rectangle);
// }
public static void main(String [] args){
Square square = new Square();
square.setLength(10);
resize(square);
}
}
打印结果2:
**************************************
长为241350****************宽为241350
长为241351****************宽为241351
长为241352****************宽为241352
长为241353****************宽为241353
长为241354****************宽为241354
**************************************
矩形类:
package com.geely.design.principle.liskovSubstitutation;
public class Rectangle {
private long length;
private long width;
public long getLength() {
return length;
}
public void setLength(long length) {
this.length = length;
}
public long getWidth() {
return width;
}
public void setWidth(long width) {
this.width = width;
}
}
正方形类:
package com.geely.design.principle.liskovSubstitutation;
public class Square extends Rectangle {
private long sideLength;
public long getSideLength() {
return sideLength;
}
public void setSideLength(long sideLength) {
this.sideLength = sideLength;
}
@Override
public long getLength() {
return getSideLength();
}
@Override
public void setLength(long length) {
setSideLength(length);
}
@Override
public long getWidth() {
return getSideLength();
}
@Override
public void setWidth(long width) {
setSideLength(width);
}
}
1.1.2 正方形矩形实现四边形
结论:
子类行为规则应与父类行为规则一致,如果子类达不到这一点,则会违背里氏替换原则,违背里氏替换原则会怎样?继承逻辑混乱,代码不便于维护
测试类:
package com.geely.design.principle.liskovSubstitutation;
public class TestSquare2 {
public static void resize(Rectangle rectangle){
while(rectangle.getWidth()<=rectangle.getLength()){
rectangle.setWidth(rectangle.getWidth()+1);
System.out.println("长为"+rectangle.getLength()+"****************宽为"+rectangle.getWidth());
}
}
// public static void main(String [] args){
// Rectangle rectangle = new Rectangle();
// rectangle.setWidth(10);
// rectangle.setLength(20);
// resize(rectangle);
// }
public static void main(String [] args){
Square square = new Square();
square.setSideLength(10);
resize(square);
}
}
四边形接口:
package com.geely.design.principle.liskovSubstitutation;
public interface Quadrangle {
long getWidth();
long getLength();
}
矩形类:
package com.geely.design.principle.liskovSubstitutation;
public class Rectangle implements Quadrangle{
private long length;
private long width;
public void setLength(long length) {
this.length = length;
}
public void setWidth(long width) {
this.width = width;
}
@Override
public long getWidth() {
return width;
}
@Override
public long getLength() {
return length;
}
}
正方形类:
package com.geely.design.principle.liskovSubstitutation;
public class Square implements Quadrangle{
private long sideLength;
public long getSideLength() {
return sideLength;
}
public void setSideLength(long sideLength) {
this.sideLength = sideLength;
}
@Override
public long getWidth() {
return sideLength;
}
@Override
public long getLength() {
return sideLength;
}
}
1.2 入参控制
1.2.1 里氏替换原则正例
结论:
重载的时候入参更加宽松,可以不引起逻辑的混乱。
测试类:
package com.geely.design.principle.liskovSubstitutation.inputmethod;
import java.util.HashMap;
public class TestChild {
public static void main(String [] args){
Child child = new Child();
HashMap hashMap = new HashMap();
child.method(hashMap);
}
}
子类:
import java.util.HashMap;
import java.util.Map; public class Child extends Base{
// @Override
// public void method(HashMap hashMap) {
// System.out.println("执行子类的HashMap方法");
// } /**
* 子类重载
* 重载的时候入参 Map比 Hashmap宽松,此时执行的时候会执行父类,不执行重载的类
* @param hashMap
*/
public void method(Map Map) {
System.out.println("执行子类Map方法");
}
}
父类:
package com.geely.design.principle.liskovSubstitutation.inputmethod;
import java.util.HashMap;
public class Base {
public void method(HashMap hashMap){
System.out.println("执行父类HashMap方法");
}
}
打印结果:
"C:\Program Files\Java\jdk1.6.0_43\bin\java.exe" "-javaagent:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\lib\idea_rt.jar=21089:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.6.0_43\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\rt.jar;F:\xiangmu3\Xin\Idea\out\production\design_pattern" com.geely.design.principle.liskovSubstitutation.inputmethod.TestChild
执行父类HashMap方法 Process finished with exit code 0
1.2.2 里氏替换原则反例
测试类:
package com.geely.design.principle.liskovSubstitutation.inputmethod;
import java.util.HashMap;
public class TestChild {
public static void main(String [] args){
Child child = new Child();
HashMap hashMap = new HashMap();
child.method(hashMap);
}
}
子类:
package com.geely.design.principle.liskovSubstitutation.inputmethod; import java.util.HashMap;
import java.util.Map; public class Child extends Base{
// @Override
// public void method(Map map) {
// super.method(map);
// } public void method(HashMap hashMap) {
System.out.println("执行子类HashMap方法");
}
}
父类:
package com.geely.design.principle.liskovSubstitutation.inputmethod; import java.util.HashMap;
import java.util.Map; public class Base {
public void method(Map map){
System.out.println("执行父类HashMap方法");
} }
打印日志:
"C:\Program Files\Java\jdk1.6.0_43\bin\java.exe" "-javaagent:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\lib\idea_rt.jar=21674:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.6.0_43\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\rt.jar;F:\xiangmu3\Xin\Idea\out\production\design_pattern" com.geely.design.principle.liskovSubstitutation.inputmethod.TestChild
执行子类HashMap方法 Process finished with exit code 0
1.3 出参控制
1.3.1 反例
结论:
子类的出参如果包含父类,会直接报错。
子类:
package com.geely.design.principle.liskovSubstitutation.outputmethod;
import java.util.Map;
public class Child extends Base {
@Override
public Object method() {
return null;
}
}
父类:
package com.geely.design.principle.liskovSubstitutation.outputmethod;
import java.util.Map;
public abstract class Base {
public abstract Map method();
}
设计模式课程 设计模式精讲 3-10 里氏替换原则coding的更多相关文章
- 北风设计模式课程---里氏替换原则(Liskov Substitution Principle)
北风设计模式课程---里氏替换原则(Liskov Substitution Principle) 一.总结 一句话总结: 当衍生类能够完全替代它们的基类时:(Liskov Substitution P ...
- "围观"设计模式(2)--里氏替换原则(LSP,Liskov Substitution Principle)
在面向对象的程序设计中.里氏替换原则(Liskov Substitution principle)是对子类型的特别定义.它由芭芭拉·利斯科夫(Barbara Liskov)在1987年在一次会议上名为 ...
- Java设计模式(4:里氏替换原则和合成复用原则详解
一.里氏替换原则 如果说实现开闭原则的关键步骤就是抽象化,那么基类(父类)和子类的继承关系就是抽象化的具体实现,所以里氏替换原则就是对实现抽象化的具体步骤的规范.即:子类可以扩展基类(父类)的功能,但 ...
- ZT 设计模式六大原则(2):里氏替换原则
设计模式六大原则(2):里氏替换原则 分类: 设计模式 2012-02-22 08:46 23330人阅读 评论(41) 收藏 举报 设计模式class扩展string编程2010 肯定有不少人跟我刚 ...
- [设计模式]<<设计模式之禅>>关于里氏替换原则
在面向对象的语言中,继承是必不可少的.非常优秀的语言机制,它有如下优点:● 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性:● 提高代码的重用性:● 子类可以形似父类,但又异于父类,“龙 ...
- 设计模式值六大原则——里氏替换原则(LSP)
里氏替换原则(Liskov Substitution Principel)是解决继承带来的问题. 继承的优点: 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性: 提高代码的重用性: 子类 ...
- 设计模式六大原则(2):里氏替换原则(Liskov Substitution Principle)
肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑.事实上原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的. 定义1:假设对每 ...
- 【设计模式六大原则2】里氏替换原则(Liskov Substitution Principle)
肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑.其实原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的. 定义1:如果对 ...
- 设计模式原则(2)--Liskov Substitution Principle(LSP)--里氏替换原则
1.定义: 所有引用基类(父类)的地方必须能透明地使用其子类的对象.这一原则与继承紧密相关.如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的 ...
随机推荐
- 每天进步一点点------H.264学习 (一)
分三个阶段学习1.第一个阶段: 学习H.264,首先要把最基本最必要的资料拿在手里.这些资料包括:标准文档+测试模型+经典文章,在本FTP中能找到.首先看 <H.264_MPEG-4 Part ...
- ElementUI+Vue在使用el-dialog时,如何做到在弹出dialog时,外部呈锁定状态,而不是点击外部导致dialog直接关闭。
ElementUI+Vue在使用el-dialog时,如何做到在弹出dialog时,外部呈锁定状态,而不是点击外部导致dialog直接关闭. 问题描述 今天,在做Element+Vue项目时发现:Di ...
- 极客从CPU选择开始-CPU详解
先来看看CPU天梯图(来自(快科技CPU性能天梯图)[https://www.mydrivers.com/zhuanti/tianti/cpu/index.html]) Intel VS AMD (P ...
- 读书笔记 - 把时间当作朋友 by 李笑来
要管理的不是时间,而是自己. 摸着石头渐行渐远,最终也能过河.- 朱敏 赛伯乐(中国)投资公司 董事长 一切都靠积累,一切都可提前准备,越早醒悟越好.人的一生是奋斗的一生,但是有的人一生过得很伟大,有 ...
- Spring Boot框架 - application.properties配置
阅读此文章之前,需要参考 https://www.cnblogs.com/mysummary/p/12238242.html 创建Spring Boot项目 建成后目录如下 一.在com.demo.s ...
- vue中使用vue-i18n 一个简单的国际化操作
1.安装:npm install vue-i18n --save-dev 2.在main.js文件中引入: import VueI18n from 'vue-i18n' Vue.use(VueI18n ...
- C++之void是什么?
void关键字的使用规则: 1. 如果函数没有返回值,那么应声明为void类型: 2. 如果函数无参数,那么应声明其参数为void: 3. 如果函数的参数可以是任意类型指针,那么应声明其参数为void ...
- Python(一)list tuple dict set
这篇文章是为了复习之前学的python的数据结构: 原文链接:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a ...
- Go语言fmt.Printf使用指南
文章引用自 fmt fmt包实现了类似C语言printf和scanf的格式化I/O.主要分为向外输出内容和获取输入内容两大部分. 向外输出 标准库fmt提供了以下几种输出相关函数. Print Pri ...
- python练习:假设s是一个字符串,返回s中十进制数字之和。例如,如果s是‘a2b3c’,则返回5。
python练习:假设s是一个字符串,返回s中十进制数字之和.例如,如果s是‘a2b3c’,则返回5. 重难点:字符串转化为字符序列.in的多种应用.try-except代码块的使用. print(& ...