终于找到了一篇文章!通俗地讲解面向对象的工作原理
日语中有一句杂俳,大意是“看不懂药品的疗效说明书,反而让人觉得药很有效”。
面向对象也有类似之处。“封装、多态和继承三种结构”“现实世界和软件是无缝的”等,当第一次听到这些时,相信不少人都会觉得“虽然不是很明白,但好像很厉害的样子”。
今天就来通俗地给大家介绍面向对象编程(Object Oriented Programming,OOP)的基本结构。
OOP 具有之前的编程语言所没有的三种优良结构,分别是类、多态和继承(一般认为OOP的三大要素为封装、多态和继承,但由于类不只具有封装的作用,所以这里改为使用“类”)。
在 OOP 刚开始普及的 20 世纪 90 年代,它们经常被称为 OOP 的三大要素。
打个比方,那些让人无从着手、难以理解的程序就像是一个乱七八糟的房间。由于无法马上在这样的房间里找到需要的东西,所以我们很有可能会再次购买,或者即使将房间里的某一处整理干净,周围也依然是乱作一团。
如果要保持房间整洁,平时就要多加注意,此外还需要使用清理不必要物品(去除冗余)的吸尘器和规整必要物品(整理)的收纳架。
为了保持房间整洁,需要吸尘器和收纳架 ▲
OOP 的三种结构为程序员提供了去除冗余逻辑、进行整理的功能结构。类结构将紧密关联的子程序(函数)和全局变量汇总在一起,创建大粒度的软件构件。通过该结构,我们能够将之前分散的子程序和变量加以整理。多态和继承能够将公用子程序无法很好地处理的重复代码进行整合,彻底消除源代码的冗余。
接下来我们将使用简单的 Java 示例代码来介绍 OOP 的基本功能。
1.1
三大要素之一:类
这里,我们将类的功能总结为汇总、隐藏和“创建很多个”。
类的功能是汇总、隐藏和“创建很多个”。
1 |
“汇总”子程序和变量。 |
2 |
“隐藏”只在类内部使用的变量和子程序。 |
3 |
从一个类“创建很多个”实例。 |
类的功能之一:汇总
代码清单 1.1 中定义了 openFile(打开文件)、closeFile(关闭文件)和readFile(读取一个字符)这三个子程序及一个全局变量。下面我们使用类的功能来逐步修改该程序。
代码清单1.1采用结构化编程的文件访问处理
首先来看一下汇总功能。类能汇总变量和子程序。这里所说的变量是指 C 和 COBOL 等语言中的全局变量。OOP 中将由类汇总的子程序称为方法,将全局变量称为实例变量(又称为“属性”“字段”),之后我们会根据情况使用这些术语。
下面就让我们使用类来汇总代码清单1.1。
代码清单1.2 使用类进行汇总
打个比方,在收拾乱七八糟的屋子时,与其只准备一个大箱子,不如准备多个箱子分别存放衣服、CD、杂志、文具和小物件等,这样会更方便拿取物品,汇总功能也是同样的道理。
类的功能之一:汇总 ▲
汇总的效果并不只是减少整体构件的数量,子程序的名称也改变了。代码清单1.1中子程序的名称是openFile、closeFile、readFile,而在代码清单1.2中则去掉了File,名称分别为open、close、read,显然这种命名方式更轻松。在没有类的结构化语言中,所有子程序都必须命名为不同的名称,而类中存储的元素名称只要在类中不重复就可以。
举例来说,一个家庭中所有成员的名字应该都不相同,但是和姓氏不同的邻居家的家庭成员重名则没有关系。
< 类的功能之一:汇总 >
能够将紧密联系的(多个)子程序和(多个)全局变量汇总到一个类中。优点如下。
● 构件的数量会减少
● 方法(子程序)的命名变得轻松
● 方法(子程序)变得容易查找
类的功能之二:隐藏
接下来我们看一下隐藏功能。
在代码清单1.2 中,子程序和全局变量都汇总到了类中,但是在这种状态下,从类的外部仍然可以访问 fileNO 变量。TextFileReader 类 的 open、read 和 close 方法会访问 fileNO 变量,但其他处理则无须访问,因此最好限定为只有这三个方法能访问该变量。
OOP 具有将实例变量的访问范围仅限定在类中的功能。加上该限定后的代码如代码清单1.3 所示。
代码清单1.3 隐藏实例变量
代码清单1.2 与代码清单1.3 只存在细微的差别。后者在实例变量的声明之前添加了 private,这是一种隐藏结构,表示将 fileNO 变量隐藏起来,限定为只有类内部的方法才能访问 fileNO 变量, 如此一来该变量就不再是全局变量了。
类的功能之二:隐藏 ▲
除了隐藏变量和方法之外,OOP 中还具备显式公开的功能。由于 TextFileReader 类中的三个方法是提供给程序的其他部分使用的,所以我们将其声明为显式公开的方法。修改后的代码如代码清单1.4 所示。
代码清单1.4 公开类和方法
由于在类和方法的声明部分指定了public,所以从应用程序的任何位置都可以对其进行调用。
< 类的功能之二:隐藏 >
能对其他类隐藏类中定义的变量和方法(子程序)。这样一来,我们在写程序时就可以不使用全局变量了。
类的功能之三:创建很多个
使用传统的编程语言很难实现“创建很多个”的结构,可以说这是 OOP 特有的功能。
代码清单1.4是一个打开文件、读取字符,最后关闭文件的程序。当只有一个目标文件时,这是没有什么问题的,但如果应用程序要比较两个文件并显示其区别,情况会怎样呢?也就是说,需要同时打开多个文件并分别读取内容。
解决这一问题的关键就在于实例。
实例是类定义的实例变量所持有的内存区域。定义了类就可以在运行时创建多个实例,也就是说,能够确保多个内存区域。
类的功能之三:创建很多个 ▲
我们在前面介绍过,类能汇总实例变量和方法。不过,如果同时创建多个实例,那么在调用方法时就不知道到底哪个实例变量才是处理对象了, 因此 OOP 的方法调用代码的写法稍微有点特殊。
存储实例的变量名 . 方法名 ( 参数 )
下面我们就来介绍一下代码清单1.4 的程序的调用端是什么样子的。请大家看代码清单1.5。
代码清单1.5 “创建很多个”实例
这里,首先从 TextFileReader 类创建两个实例,并存储到 reader1 和 reader2 这两个变量中。之后的打开文件、读取字符及关闭文件等处理都是通过指定变量 reader1 和 reader2 来调用方法的。
像这样,通过“指定实例,调用方法”,就可以指定哪个实例变量是处理对象。
根据“创建很多个”的结构,类中方法的逻辑就变得简单了。
< 类的功能之三:创建很多个 >
一旦定义了类,在运行时就可以由此创建很多个实例。
这样一来,即使同时处理文件、字符串和顾客信息等多个同类信 息,也可以简单地实现该类内部的逻辑。
总结:
<OOP 的三大要素之一:类>
类是“汇总”“隐藏”和“创建很多个”的结构。
1 |
“汇总”子程序和变量。 |
2 |
“隐藏”只在类内部使用的变量和子程序。 |
3 |
从一个类“创建很多个”实例。 |
1.2
三大要素之二:实现调用端公用化的多态
接着我们来看一下三大要素中的第二个要素——多态(polymorphism)。顾名思义,多态具有“可变为各种状态”的含义。
简单地说,多态可以说是创建公用主程序的结构。公用主程序将被调用端的逻辑汇总为一个逻辑,而多态则相反,它统一调用端的逻辑。
多态的结构 ▲
<OOP 的三大要素之二:多态>
多态是统一调用子程序端的逻辑的结构,即创建公用主程序的结构。
大家可能会觉得“公用主程序”这样的说法有点陈旧,但绝不可小瞧多态。虽说多态只是实现了程序调用端的公用化,但其重要性绝不亚于前面提到的类。
在 OOP 出现之前,公用子程序就已经存在了,但公用主程序并没有出现。框架和类库等大型可重用构件群也正是因为多态的存在才成为可能。因此,将多态称为与子程序并列的两项重大发明也不为过。
1.3
三大要素之三:去除类的重复定义的继承
OOP 三大要素中的最后一个要素是继承。
简单地说,继承就是“将类的共同部分汇总到其他类中的结构”。通过利用该结构,我们可以创建一个公用类来汇总变量和方法,其他类则可以完全借用其定义。
继承的结构 ▲
在 OOP 之前的由子程序构成软件的编程环境中,我们会创建一个公用子程序来汇总重复的命令群。同理,在由类构成软件的 OOP 环境中,我们可以创建一个公用类来汇总变量和方法。
也就是说,不仅局限于通过前面 介绍的多态来统一调用端,而且还要汇总相似的类中的共同部分。这是一种通过尽可能多地提供功能来让编程变轻松的思想。
在使用继承的情况下,我们将想要共同使用的方法和实例变量定义在公用类中,并声明想要使用的类继承该公用类,这样就可以直接使用公用类中定义的内容。在OOP 中,该公用类称为超类,利用超类的类称为子类。
我们可以这样理解:继承是将类定义的共同部分汇总到另外一个类中,并去除重复代码的结构。
另外,声明继承也就是声明使用多态。因此,在声明继承的子类中,为了统一方法调用方式,继承的方法的参数和返回值类型必须与超类一致。
继承和多态 ▲
<OOP 的三大要素之三:继承>
继承是将类定义的共同部分汇总到另外一个类中,并去除重复代码的结构。
1.4
对三大要素的总结
整理一下可以得到这个表:
这三种结构并不是分别出现的,在最初的面向对象语言 Simula 67 中 就拥有这三种结构,真是让人惊叹。提起 1967 年,就不得不提到无 GOTO 编程,这真是不平凡的一年。OOP 可以看作结构化语言的发展形式,但考虑到它在那个时代就出现了,因此说是编程语言的突然变异也不为过。
——本文选自《面向对象是怎样工作的》
面向对象是具有实践性的思想,现在需要的是“能够使用的面向对象”,而其关键就存在于软件开发的历史中。
通过阅读本书,大家就能够理解为什么面向对象作为一种编程技术,会影响设计作业、分析作业,甚至整个软件开发流程。(点击「阅读原文」查看目录和试读。)
日系图文并茂
更简单更直白的计算机知识手册
文末畅聊
#谈谈你对面向对象编程的理解
精选留言中随机挑选1位小伙伴
赠送
《面向对象是怎样工作的》纸质书一本
活动截止到12月27日24:00
推 荐 阅 读
如果现在只能用汇编和 Goto 编程......
图 灵 社 群
终于找到了一篇文章!通俗地讲解面向对象的工作原理相关推荐
- 【python实例6.5】一篇文章让你弄懂政府工作报告词云~总结笔记
一篇文章让你弄懂政府工作报告词云 1.安装wordcloud库 2.新时代中国特色社会主义的词云 wordcloud下载链接: https://www.lfd.uci.edu/~gohlke/pyth ...
- 大白话讲解卷积神经网络工作原理
本文介绍了计算机视觉常用工具:卷积神经网络.用大白话讲解了其应用领域.卷积.池化(下采样).全连接.梯度下降.反向传播算法.并用三维可视化工具展示了手写字体识别的卷积神经网络案例,最后介绍了几个经典的 ...
- 小车自动往返工作原理_自动门厂家为你讲解各类自动门工作原理
自动门厂家为你讲解各类自动门工作原理 凯撒自动门作为一家专业门控企业,自动门生产厂家,畅谈各种自动门的概念和工作原理.凯撒门控公司认为,自动门是指当人们接近或离开时能够自动打开和关闭的门扇.门扇的智能 ...
- 第二章 MCS-51单片机硬件结构与工作原理
第二章 MCS-51单片机硬件结构与工作原理 2.1 MCS-51单片机的硬件结构 2.2 引脚介绍 2.3 复位电路 2.4 寄存器 2.5 时序 2.6 MCS-51的工作方式 2.1 MCS-5 ...
- 【电机学习笔记】第一章 了解交流电机的结构以及工作原理
系列文章目录 第一章 了解交流电机的结构以及工作原理 文章目录 系列文章目录 文章目录 前言 一.交流电机的构成 二.同步与异步的区别 三. 交流电机的运动原理 前言 由于交流电力系 ...
- 一篇文章搞定GVIM(根据工作经验持续更新)
文章目录 0.引言 1.在Linux下面安装VIM 2.基本操作 2.1三种模式 2.1 保存退出:wq没反应?! 2.2 解决鼠标不能用的问题 2.3 VIM上下左右移动hjkl 2.4 跳转到第n ...
- 通俗易懂的讲解二极管三极管工作原理
本文转自:https://www.zhihu.com/question/25032358 https://blog.csdn.net/a10615/article/details/51627619 先 ...
- 一篇文章彻底弄懂零拷贝底层原理
前言 零拷贝是网络编程的关键,很多性能优化都离不开零拷贝,很多优秀的开源框架底层都用的零拷贝,如Netty.RocketMQ.Spark等 正文 1. 再看IO 在深入零拷贝机制之前,先来了解下传统B ...
- 一篇文章带你吃透VUE响应式原理
本篇响应式原理介绍比较长,全文大概1w+字.虽然内容繁杂,但阅读过后,绝对会让你对vue的响应式有更加深刻的理解. 分块阅读,效果更佳.(建议读者有一定vue使用经验和基础再食用) 首先上图,下面这张 ...
最新文章
- SQL Server的WAITFOR DELAY注入
- python之父去面试-Python面试题之Python的Super方法
- python判断txt文件是否为空_Python中的空值怎么判断
- js获取被点击的元素以及子元素
- macOS zip 打包加密和 unzip 解压
- 自定义报表预览控制工具条
- bmp180气压传感器工作原理_陕西压力传感器的工作原理信息推荐
- 动态规划求解所有字符的组合数
- 计算二叉树的叶子结点个数_C++数据结构二叉树统计总结点个数,叶子结点个数,单分支结点个数,双分支结点个数。...
- ​每一页都是知识点,这本Flutter企业级实践指南太绝了
- 用C#实现文件夹拷贝
- ubuntu14.4安装GTK\opencv和pythoy opencv
- html5 绘制思维导图,Qunee组件制作思维导图
- JWT实现接口双重认证,提供安全又不复杂的接口安全能力
- php 展示微信图片尺寸,微信公众平台图片最大尺寸
- linux swap空间不足,swap空间不足问题解决
- android中实现微信九宫格,微信小程序九宫格布局
- python 颜色与字体
- GraphicsMagick创建空白图片
- ettercap局域网DNS欺骗实现过程
热门文章
- matlab 二值化_MATLAB实验,图像二值化处理
- 当前主要使用的python版本_如何获取当前使用的Python版本信息?(代码示例)
- brave浏览器_兼容Chrome 插件的Brave浏览器,带给你更快速的上网冲浪体验
- appcontroller.php,php用什么开发app接口
- Android SDK Tools Setup 提示 “ java se development kit not found”
- 提高ActiveMQ工作性能
- python调用脚本或shell的方式
- 添加时间数据时 出现多一天或者少一天的问题 解决方案
- hadoop错误,重新格式化namenode后,出现java.io.IOException Incompatible clusterIDs
- redis的导入导出需要特别注意的地方