oo中的继承性的思考和说明

1、继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契约,虽然它不强制要求所有的子类必须遵循这些七月,但是如果子类对这些已经实现的方法任意修改,就会对整个继承体系造成破坏。

2、继承在给程序设计带来便利的同时,也带来了弊端。比如使用继承会给程序带来侵入性,程序的可移植性降低,增加对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能产生故障。

3、问题提出:在编程中,如何正确的使用继承? 答:尽可能遵循里氏替换原则。

基本介绍

1、里氏替换原则在1988年,由麻省理工学院的一位姓里的女士提出的。

2、如果对每个类型为T1的对象o1,都有类型为T2的对象o2,使得T1定义的所有程序p在所有的对象o1都代换成o2是,程序p的行为没有发生变化,那么类型T2是类型T1的子类型。换句话说,所有,所有应用类型的地方必须能透明地使用其子类的对象。

3、在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法。

4、里氏替换原则告诉我们,继承实际上让两个类耦合性增强了,在适当的情况下,可以通过聚合,组合,依赖来解决问题

应用案例

没有使用里氏替换原则

  1. public class Liskov {
  2. public static void main(String[] args) {
  3. A a = new A();
  4. System.out.println("1-8=" + a.func1(1, 8));
  5. System.out.println("--------------------");
  6. B b = new B();
  7. System.out.println("11-3=" + b.func1(11, 3));
  8. System.out.println("1-8=" + b.func1(1, 8));
  9. System.out.println("11+3+9=" + b.func3(11, 3));
  10. }
  11. }
  12. class A {
  13. // 两个数的差
  14. public int func1(int num1, int num2) {
  15. return num1 - num2;
  16. }
  17. // 两个数的积
  18. public int funcBase(int num1, int num2) {
  19. return num1 * num2;
  20. }
  21. }
  22. //B类继承了A
  23. //增加了一个新功能,完成两个数相加,然后和9求和
  24. class B extends A {
  25. // 这里,重写了A的方法,可能是无意识
  26. public int func1(int a, int b) {
  27. return a + b;
  28. }
  29. public int func3(int a, int b) {
  30. return func1(a, b) + 9;
  31. }
  32. }

使用里氏替换原则

  1. public class Liskov {
  2. public static void main(String[] args) {
  3. A a = new A();
  4. System.out.println("1-8=" + a.func1(1, 8));
  5. System.out.println("--------------------");
  6. B b = new B();
  7. System.out.println("11-3=" + b.func1(11, 3));
  8. System.out.println("1-8=" + b.func1(1, 8));
  9. System.out.println("11+3+9=" + b.func2(11, 3));
  10. // 使用组合来使用A的相关方法
  11. System.out.println("--------------------");
  12. System.out.println("11-3=" + b.func3(11, 3));
  13. System.out.println("1-8=" + b.func3(1, 8));
  14. System.out.println("11+3+9=" + b.func2(11, 3));
  15. }
  16. }
  17. class Base {
  18. // 把更加基础的方法和成员写到Base类
  19. // 两个数的积
  20. public int funcBase(int num1, int num2) {
  21. return num1*num2;
  22. }
  23. }
  24. class A extends Base {
  25. // 两个数的差
  26. public int func1(int num1, int num2) {
  27. return num1 - num2;
  28. }
  29. }
  30. //B类继承了A
  31. //增加了一个新功能,完成两个数相加,然后和9求和
  32. class B extends Base {
  33. // 如果B需要使用A类得方法,使用组合关系
  34. private A a = new A();
  35. // 这里,重写了A的方法,可能是无意识
  36. public int func1(int a, int b) {
  37. return a + b;
  38. }
  39. public int func2(int a, int b) {
  40. return func1(a, b) + 9;
  41. }
  42. // 使用A得方法
  43. public int func3(int a, int b) {
  44. return this.a.func1(a, b);
  45. }
  46. }

上面这段代码中,使用了里氏替换原则,将更基础的方法funcBase()提取出来,然后将A类和B类继承这个更基础的Base类,采用依赖、聚合或耦合的方式来减少父类和子类的耦合

java设计模式学习笔记——里氏替换原则的更多相关文章

  1. java设计模式学习笔记--接口隔离原则

    接口隔离原则简述 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应建立在最小的接口上 应用场景 如下UML图 类A通过接口Interface1依赖类B,类C通过接口Interface1依赖类 ...

  2. java设计模式学习笔记--单一职责原则

    单一职责原则注意事项和细节 1.降低类的复杂度,一个类只负责一项职责 2.提高可读性,可维护性 3.降低变更引起的风险 4.通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单 ...

  3. java设计模式学习笔记--开闭原则

    基本介绍 1.开闭(ocp)原则时编程中最基础.最重要的设计原则 2.一个软件实体如类.木块和函数应该对扩展开放,对修改关闭.用抽象构建框架,用实现扩展细节.即对提供方开放,对使用方关闭. 3.当软件 ...

  4. java设计模式学习笔记--依赖倒转原则

    依赖倒转原则简述 1.高层模块不应该依赖低层模块,二者都应该依赖其抽象 2.抽象不应该依赖细节,细节应该依赖抽象 3.依赖倒转得中心思想时面向接口编程 4.依赖倒转原则时基于这样得设计理念:相对于细节 ...

  5. java设计模式学习笔记--浅谈设计模式

    设计模式的目的 编写软件的过程中,程序员面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战.设计模式为了让程序具有更好的 1.代码重用性(即:相同功能的代码,不用多次编写) ...

  6. Java设计模式学习笔记(三) 工厂方法模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...

  7. Java设计模式学习笔记(五) 单例模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 使用单例模式的原因 以Windows任务管理器为例,在Windows系统中,任务管理器是唯 ...

  8. C#设计模式学习笔记:设计原则

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8287784.html,记录一下学习过程以备后续查用. 写代码也是有原则的,我们之所以使用设计模式,主要是为了 ...

  9. Java设计模式学习笔记(二) 简单工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...

随机推荐

  1. 12、python文件的操作

    前言:本文主要介绍python中文件的操作,包括打开文件.读取文件.写入文件.关闭文件以及上下文管理器. 一.打开文件 Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处 ...

  2. Java容器解析系列(15) HashTable Dictionary & Properties

    HashTable的实现原理与HashMap没有什么区别; 其与HashMap的主要区别如下: 添加进入jdk时间:HashTable在jdk1.0时添加,HashMap在jdk1.2时添加; 类签名 ...

  3. robotframework,移动端(小程序)自动化,获取元素属性值的方法

    如下图,获取商品价格 属性值显示在content-desc内 传统的get text指定是无法获得到这个元素指定属性的值的 只有通过使用AppiumLibrary.get element attrib ...

  4. sqli_labs学习笔记(一)Less-1~Less-20

    开门见山 Less-1 GET - Error based - Single quotes - String(基于错误的GET单引号字符型注入) ·  方法一:手工UNION联合查询注入 输入单引号, ...

  5. qt creator源码全方面分析(0)

    本人主攻C++和Qt. 上两天刚研究完Qt install framework(IFW)应用程序安装框架. google没发现有正儿八经的官方文档的翻译,我就进行了翻译哈!! 系列文章具体见:http ...

  6. Spring Cloud服务注册中心交付至kubernetes

    前言 服务发现原则: 各个微服务在启动时,会将自己的网络地址等信息注册到服务发现组件中,服务发现组件会存储这些信息 服务消费者可以从服务发现组件中查询到服务提供者的网络地址,并使用该地址来远程调用服务 ...

  7. Centos 7 最小化Gitlab部署操作

    Gitlab的介绍 gitlab是一个版本控制的集群软件,集成了git.postgresql.Ruby.nginx.redis等重要应用工具: gitlab分为ce和ee版本:CE是社区版,EE是企业 ...

  8. python人脸识别

    需要掌握知识python,opencv和机器学习一类的基础 过一段时间代码上传github,本人菜j一个,虽然是我自己谢的,也有好多不懂,或者我这就是错误方向 链接:https://pan.baidu ...

  9. ROS中3D机器人建模(五)

    一.创建一个差速驱动移动机器人模型 前面我们已经创建了一个7-DOF机械臂机器人模型,接下来我们将创建一个差速机器人模型,差速轮式机器人在机器人底盘的两端安装两个轮子, 整个底盘由一个或两个脚轮支撑. ...

  10. 自学Java第三章——《流程控制语句结构》

    流程控制语句结构分为: 1.顺序结构:从上到下依次执行 2.分支结构:多个分支选择其中一个分支执行 3.循环结构:重复执行某些代码 3.1 顺序结构 执行过程:从上到下顺序执行 3.1.1 输出语句 ...