【总结记录】面向对象设计OOP三大特性(封装、继承、多态)、七大基本原则的理解(结合代码、现实实例理解)

文章目录

  • 一. 三大特征的理解
      • (1)封装
      • (2)继承
      • (3)多态
      • (4)面向对象、面向过程的对比
  • 二. 七大基本原则的理解
      • (1)单一职责原则
      • (2)开放封闭原则(OOP 核心)
      • (3)里氏替换原则(OOP 标志)
      • (4)依赖倒置原则
      • (5)接口分离原则
      • (6)迪米特原则(最少知识法则)
      • (7)组合优先继承原则

拖了好久的总结= =。
对 OOP 的内容零散地看了一些,想了一些还是自己写一个总结来提升一下理解吧!
学好 OOP,也利于设计模式的学习~
一点自己的见解,疏漏错误的地方期待大佬在评论区指正~
文章定义、实例等参考了《大话设计模式》、什么是OOP、OOP七大原则等书籍、文章,感谢~

一. 三大特征的理解

(1)封装

  • 定义:每个对象都包含它能进行操作所需要的所有信息

  • 好处

    1. 减少耦合
    2. 内部实现可以自由修改
    3. 类具有清晰的对外接口
  • 例子:房子,用墙壁封装起来。

    1. 窗户、门口就是对外接口:设想一下,如果没有门窗(或者门窗是秘密暗道,不清晰),我们无法进入房子来使用里面的家具,那这个房子还有用吗?(清晰对外接口的必要性
    2. 改变房间布局就是修改类内部:我的房子想怎么改就怎么改,不会给房外人带来困扰(自由修改内部的体现
    3. 减少耦合:我想到的例子是合租;耦合度过高,相当于大家的房子都连在一起(没有墙壁封装),耦合度过高带来的问题,就是不必要的相互联系:比如我在家用着100寸电视打游戏,你家高三孩子无法避免地看到了,导致无心向学。而墙壁的封装就可以避免这个不必要的互相联系,也就是达到减小耦合度的效果。

    图源网络,侵删

(2)继承

  • 定义:子类可以理解为对父类的特殊化,除了具备父类特性外,还具备自己的独立个性。
    1. 子类拥有父类非 private 的属性和功能
    2. 子类具有自己的属性和功能(拓展)
    3. 子类可以用自己的方式实现父类的功能(重写)
  • 好处
    1. 提高代码复用率
    2. 易拓展
  • 缺点:父类变,则子类不得不变——继承会破坏(1)的封装性
    可以看到(1)的好处2【自由修改】。显而易见,继承会威胁到这一效果:
    父类的自由修改,可能会导致子类出现问题(比如新增抽象函数)。
  • 这也显示着,继承是一种类与类之间强耦合的关系

因此,有一项“组合优先于继承”的原则,可以到下面的原则(7)再看一下~

  • 例子:虽然大家应该都对继承熟悉了,不过这边还是写一个吧~
    大凡是小凡的爹,因此小明和大明一样都是黄种人(父类特征
    虽然是大凡不会rap,但是小凡会(子类拓展
    大凡唱歌,唱高音;小凡唱歌,唱电音(方法重写
    大凡改变肤色,变成黑人,小凡也得变成黑人(破坏封装性,不能自由修改内部

    联动一下计网,URI和URL也可以看成继承关系噢~(URL 是对 URI 的特殊化)

(3)多态

  • 定义不同对象执行相同动作,但要通过对象自己的代码执行。
    1. 子类以父类身份出现(对象声明必须是父类
    2. 子类以自己方式实现(无论对象是否转换成父类,都用的继承链末端方法)
    3. 子类特有属性和方法不可使用
  • 优点:提高了代码的维护性、拓展性
  • 例子:这里直接用《大话设计模式》里的例子,这个讲的挺好的:
    京剧艺术家大明,和子承父业的儿子小明。父亲表演当前生病了,小明代父表演:
    小明穿大明的戏服,以大明的身份进行表演(父类身份
    小明还是以自己的理解进行表演(自己方式
    小明虽然说学了一手Breaking,但是父亲不会,所以不能使用(特有属性方法不可用
  • 重载,算多态吗:按照上面的定义来看,应该不算。但是也有说算是静态多态的。总的来说应该是看具体定义,看成一种多态应该也是可以的。

(4)面向对象、面向过程的对比

各自相对优点:

  • 面向过程:效率更高。(具体化、流程化,不用进行实例化过程)
  • 面向对象:易维护、易复用、易扩展。(三大特性)

二. 七大基本原则的理解

诶,网上很多都是五大原则,为了全面点,我这边还是写七个的吧~

(1)单一职责原则

  • 定义:一个类,应该有且只有一个引起它变化的原因
  • 好处
    1. 耦合度低,变更引起的风险降低,提高可维护性
    2. 类的职责明确,增加代码可读性
  • 例子:两种手机类,按照单一职责原则,手机应该只负责通话。
    过多的功能,会提高类的复杂度,同时提高了耦合度。
    (当然,显示中手机还是按照多种多样的来的,这里只是想表达一下)
class BadPhone {// 包括手电筒、相机、通话功能的手机类private int flashlightBrightness;private int cameraPixel;private int volume;public void flashlightFunctions() { }public void cameraFunctions() { }public void conversationFunctions() { }
}class GoodPhone {// 包括通话功能的手机类private int volume;public void conversationFunctions() { }
}

(2)开放封闭原则(OOP 核心)

  • 定义:软件实体,应该是可以拓展,但是不可修改
  • 理解:一个类提供的外部可用接口,如果由于新的需求进行了修改,可能会导致依赖这个接口的其他方法瘫痪。解决方法就是通过拓展新接口,而非修改旧接口来实现新需求。
  • 好处:可维护、可拓展、可服用、灵活性好(全包!)
  • 例子:getID() 返回 String,printID() 依赖 getID()。现在多了一个返回 int 型 ID 的需求。
class MyClass2 {public String getID() {return "ID";}// Bad
//    public int getID() {
//        return 123;
//    }// Goodpublic int getIntID() {return 123;}public void printID() {// 如果修改 getID(),依赖 getID() 的 printID() 就会出错// 但是拓展 getIntID(),就没问题System.out.printf("%s", getID());}
}

(3)里氏替换原则(OOP 标志)

  • 定义:子类型必须能够替换掉父类型。
  • 优点:保证使用父类的模块在无需修改的情况下就能拓展,提升拓展性。
  • 例子:举个开枪的例子吧~
class Gun {public void shoot() {System.out.println("fire!");}
}class GoodGun extends Gun {@Overridepublic void shoot() {System.out.println("fire! fire!");}
}class BadGun extends Gun {@Overridepublic void shoot() {System.out.println("sorry, I can't fire");}
}class Man {public void fire() {new Gun().shoot();// new GoodGun().shoot(); 可以替换,能开枪// new BadGun().shoot(); 不能替换,不能开枪}
}

(4)依赖倒置原则

  • 定义抽象不应该依赖细节细节应该依赖于抽象
  • 理解:针对接口,而非实现进行编程。
  • 例子:写一个项目A,用到 Redis(高层模块项目A,依赖于低层模块 Redis)。如今由于机子太烂,日常宕机,因此打算换成 etcd 来避免数据丢失的问题。
    问题来了,由于项目A的代码绑定了 Redis,因此无法复用项目A的代码,这就问题很大~如何解决呢?如果项目A的代码依赖的不是Redis,而是抽象的 K-V 数据库,具有稳定的接口(也就是依赖于抽象),那就可以直接替换成 etcd 啦~

讲道理,我不会 Redis、etcd,这里的例子是大概举出来的,有误的话欢迎指出~

(5)接口分离原则

  • 定义:客户端不应该依赖它不需要的接口。采用多个与特定客户类有关的接口,比采用一个通用的接口要好。
  • 理解:相对于(1)单一职责原则(注重业务逻辑划分),这里要求的是接口的方法尽量少
  • 好处
    1. 避免接口污染
    2. 高内聚(一个软件模块是由相关性很强的代码),毕竟用多个合适接口啦~
    3. 灵活性
  • 例子:实现老人机类,一个复杂的手机接口 VS 多个简单的功能接口
interface BadPhoneInterface {void fly();void swim();void watchTV();void buy();void talk();void sendMessage();
}// 老人机:只希望能打电话、发短信就好
// 非接口分离:采用了具有多个方法的接口,并非高聚合
class OldPhone1 implements BadPhoneInterface {@Overridepublic void fly() { }@Overridepublic void swim() { }@Overridepublic void watchTV() { }@Overridepublic void buy() { }@Overridepublic void talk() { }@Overridepublic void sendMessage() { }
}// 接口分离:高聚合,灵活,定制化~
interface Talker {void talk();
}interface MessageSender {void sendMessage();
}class OldPhone2 implements Talker, MessageSender {@Overridepublic void talk() { }@Overridepublic void sendMessage() { }
}

(6)迪米特原则(最少知识法则)

  • 定义:如果两个类不必彼此直接通信,那么这两个类就不应该发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法,可以通过第三者转发调用
  • 理解:根本思想是强调类之间的松耦合,促进了类的复用
  • 例子:秋招时节~举一个求职例子吧!(当然,具体面试流程肯定没我瞎写的这么糙)
    小红想进大厂A,于是花了大功夫认识了面试官1投简历,希望面试官1过几天能面她。
    但是~还没来得及面,面试官1就跳槽了!那小红接下来该怎么办,继续花大时间来找面试官2、面试官3吗?这就是没有遵循迪米特原则了:
    小红和(具体)面试官之间,不应该有直接的联系,这样耦合太高了。而应该是找HR!让HR来充当这个转发“求面试调用”的第三者,这样耦合度低,而且不会发生像上面那样的事情了^ ^

(7)组合优先继承原则

  • 定义:能用组合的地方就不要继承,以保证封装性

    (6)(7)的代码有空再补了。。敲累了摆烂
    花了一下午我是没想到的= =
    希望这个总结能帮助读者有更多的OOP理解,感谢你能阅读到这里~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/504166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql 递归查找父节点_MYSQL递归查询所有父节点

1、表结构:CREATE TABLE t_busi_system (ID varchar(64) NOT NULL COMMENT 标识,PARENT_ID varchar(64) DEFAULT NULL COMMENT 父id,CREATE_DATE varchar(64) DEFAULT NULL COMMENT 创建时间,CREATE_USER_ID varchar(64) DEFAULT NULL COMMENT 创建人id,CREATE_USER…

arcmap shp导出cad无反应_如何使用ArcMap将Excel数据转换为shp数据

1. 概述对ArcMap而言,除了shapefile等数据源,还可以将包含地理位置的表格数据以 XY 坐标的形式添加到地图中,比如Excel格式的数据,如果包含有坐标数据在里面,就可以通过导入XY数据的方式将Excel数据导入,最…

【总结记录】《MySQL必知必会》读后笔记,结合 leetcode 例题理解

文章目录一. 《MySQL知会》读后笔记1. 零散的前文知识2. 连接数据库3. 检索数据(重点开始了)4. 排序、过滤数据5. 通配符、正则表达式6. 汇总数据7. 分组数据(1)GROUP BY(数据分组)(2&#xff0…

新松机器人发行价_知识创造财富,“机器人第一股”背后的院士是怎样炼成的?...

‍*本文原创首发于微信公众号“德先生”,未经授权转载必究。机器人的研发、制造、应用,是衡量一个国家科技创新和高端制造业水平的重要标志。上世纪70年代,我国机器人刚刚起步,如今,中国自主品牌机器人依靠技术创新&am…

如何使用CNN进行物体识别和分类_RCNN物体识别

R-CNN,图片识别目标检测(Object Detection)是图像分类的延伸,除了分类任务,还要给定多个检测目标的坐标位置。R-CNN是最早基于CNN的目标检测方法,然后基于这条路线依次演进出了SPPnet,Fast R-CNN和Faster R-CNN,然后到…

python如何不跳行打印_python怎么不换行打印

Python2.7中,执行完print后,会自动换行,如下代码会打印:abc\n123\n(其中\n代表换行)print (abc)print (123)如何实现不换行打印字符呢,下面介绍Python2.7中 实现不换行打印字符的3种简单方法:1.在print函数…

【LeetCode 总结】Leetcode 题型分类总结、索引与常用接口函数

文章目录零. Java 常用接口函数一. 动态规划二. 链表三. 哈希表四. 滑动窗口五. 字符串六. DFS、BFS七. 二分法八. 二叉树九. 偏数学、过目不忘 and 原地算法等十. 每日一题前言: 是时候开一个对于我的 LeetCode 专栏的总结索引了 虽然说大概只刷了150道左右&#…

nfs服务器_Kubernetes集群下部署NFS持久存储

NFS是网络文件系统Network File System的缩写,NFS服务器可以让PC将网络中的NFS服务器共享的目录挂载到本地的文件系统中,而在本地的系统中来看,那个远程主机的目录就好像是自己的一个磁盘分区一样。kubernetes使用NFS共享存储有两种方式&…

c语言 指针_C 语言指针详解

(给CPP开发者加星标,提升C/C技能)作者:C语言与CPP编程 / 自成一派123(本文来自作者投稿)1为什么使用指针假如我们定义了 char a’A’ ,当需要使用 ‘A’ 时,除了直接调用变量 a ,还可以定义 char *p&a &#xff0c…

kettle 插入更新 数据增量_使用Kettle工具进行增量数据同步

增量同步的方式有很多种,我使用的是: 快照表 触发器需求:当主库库表发生增删改时,从库库表与主库库表数据保持一致。环境:1、Mysql2、kettle 7.1思路:1、在主库中,将需要同步的库表新建快照表,…

idea修改代码后不重启项目_使用DevTool实现SpringBoot项目热部署

前言最近在开发的时候,每次改动代码都需要启动项目,因为有的时候改动的服务比较多,所以重启的次数也就比较多了,想着每次重启等待也挺麻烦的,就打算使用DevTools工具实现项目的热部署热部署是什么大家都知道在项目开发…

vue 计算文件hash值_vue的hash值原理,也是table切换。

.pages>div{display: none;}aaabbbcccc首页关于我的页面用户中心//hash 和页面一一对应起来//router 配置var router [{path:"/",component:document.getElementById("home")},{path:"/about",component:document.getElementById("abou…

c++ 单例模式_Redis单例、主从模式、sentinel以及集群的配置方式及优缺点对比

redis作为一种高效的缓存框架,使用是非常广泛的,在数据存储上,在运行时其将数据存储在内存中,以实现数据的高效读写,并且根据定制的持久化规则不同,其会不定期的将数据持久化到硬盘中。另外相较于其他的NoS…

jenkins 插件目录_10 个 Jenkins 实战经验,助你轻松上手持续集成

众所周知,持续构建与发布是我们日常工作中要面对的的一个重要环节,目前很多公司都采用 Jenkins 来搭建符合需求的 CI/CD 流程,作为一个持续集成的开源工具,它以安装启动方便,配置简单,上手容易的特点&#…

手机python3l运行_Python3 os.lchflags() 方法

Python3 os.lchflags() 方法概述os.lchflags() 方法用于设置路径的标记为数字标记,类似 chflags(),但是没有软链接。只支持在 Unix 下使用。语法lchflags()方法语法格式如下:os.lchflags(path, flags)参数path -- 设置标记的文件路径flags --…

jdbc 批量insert_JDBC相关知识解答

1. JDBC_PreparedStatement插入大量数据_批处理插入_效率比较(1) jdbc新增大量数据时, 如何处理能提高效率?答:使用批处理提高效率(2) 什么是批处理? JDBC如何进行批处理?答:批处理:在与数据库的一次连接中,批量的执行条 SQL 语…

lin通信ldf文件解析_lin ldf

Baby-LIN 采用闪存来保存固件, 因此更新和升级非常简便。 Baby-LIN 的软件套装是 LINWorks。这个软件包包括几个不同的应用程序。 LINWorks LDF-Editor 可以检查、......并且在未加载 LDF/SDF 文件的情况下,也可以用来监测与记录总线数据。 Baby-LIN-DLL 库文件可让用户编写应用…

vue项目使用大华摄像头怎样初始化_Vue接入监控视频技术总结

最近一直在搞监控视频接入方面的事情,积累了不少的经验,这里总结一下。提前说一句,本文提到的视频接入均是以RTSP为基础转码而来的,至于用海康大华等插件播放的咱们就闭口不提了可以看这个文章,在vue中接入ocx控件播放…

python 实现显著性检测_强!汽车车道视频检测:python+OpenCV为主实现

1 说明:1.1 完整版:汽车车道动态视频检测讲解和注释版代码,小白秒懂。1.2 pythonOpenCVmoviepynumpy为主的技术要点。1.3 代码来源:https://github.com/linghugoogle/CarND-Advanced-Lane-Lines #虽然感觉也是fork别人的&#xff…

var和function谁先优先执行_变量var声明和函数function声明优先级

变量声明优先级使用var关键字和function关键字声明的变量,会被JS的解释器优先解析执行,具有优先级使用var关键字声明变量1. 看代码说话// 在script中直接打印输出变量aconsole.log(a); // Uncaught ReferenceError: a is not defined2. 看代码说话consol…