日语中有一句杂俳,大意是“看不懂药品的疗效说明书,反而让人觉得药很有效”。

面向对象也有类似之处。“封装、多态和继承三种结构”“现实世界和软件是无缝的”等,当第一次听到这些时,相信不少人都会觉得“虽然不是很明白,但好像很厉害的样子”。

今天就来通俗地给大家介绍面向对象编程(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 编程......

图 灵 社 群

终于找到了一篇文章!通俗地讲解面向对象的工作原理相关推荐

  1. 【python实例6.5】一篇文章让你弄懂政府工作报告词云~总结笔记

    一篇文章让你弄懂政府工作报告词云 1.安装wordcloud库 2.新时代中国特色社会主义的词云 wordcloud下载链接: https://www.lfd.uci.edu/~gohlke/pyth ...

  2. 大白话讲解卷积神经网络工作原理

    本文介绍了计算机视觉常用工具:卷积神经网络.用大白话讲解了其应用领域.卷积.池化(下采样).全连接.梯度下降.反向传播算法.并用三维可视化工具展示了手写字体识别的卷积神经网络案例,最后介绍了几个经典的 ...

  3. 小车自动往返工作原理_自动门厂家为你讲解各类自动门工作原理

    自动门厂家为你讲解各类自动门工作原理 凯撒自动门作为一家专业门控企业,自动门生产厂家,畅谈各种自动门的概念和工作原理.凯撒门控公司认为,自动门是指当人们接近或离开时能够自动打开和关闭的门扇.门扇的智能 ...

  4. 第二章 MCS-51单片机硬件结构与工作原理

    第二章 MCS-51单片机硬件结构与工作原理 2.1 MCS-51单片机的硬件结构 2.2 引脚介绍 2.3 复位电路 2.4 寄存器 2.5 时序 2.6 MCS-51的工作方式 2.1 MCS-5 ...

  5. 【电机学习笔记】第一章 了解交流电机的结构以及工作原理

    系列文章目录 第一章  了解交流电机的结构以及工作原理 文章目录 系列文章目录 文章目录 前言 一.交流电机的构成 二.同步与异步的区别 三. 交流电机的运动原理 前言         由于交流电力系 ...

  6. 一篇文章搞定GVIM(根据工作经验持续更新)

    文章目录 0.引言 1.在Linux下面安装VIM 2.基本操作 2.1三种模式 2.1 保存退出:wq没反应?! 2.2 解决鼠标不能用的问题 2.3 VIM上下左右移动hjkl 2.4 跳转到第n ...

  7. 通俗易懂的讲解二极管三极管工作原理

    本文转自:https://www.zhihu.com/question/25032358 https://blog.csdn.net/a10615/article/details/51627619 先 ...

  8. 一篇文章彻底弄懂零拷贝底层原理

    前言 零拷贝是网络编程的关键,很多性能优化都离不开零拷贝,很多优秀的开源框架底层都用的零拷贝,如Netty.RocketMQ.Spark等 正文 1. 再看IO 在深入零拷贝机制之前,先来了解下传统B ...

  9. 一篇文章带你吃透VUE响应式原理

    本篇响应式原理介绍比较长,全文大概1w+字.虽然内容繁杂,但阅读过后,绝对会让你对vue的响应式有更加深刻的理解. 分块阅读,效果更佳.(建议读者有一定vue使用经验和基础再食用) 首先上图,下面这张 ...

最新文章

  1. SQL Server的WAITFOR DELAY注入
  2. python之父去面试-Python面试题之Python的Super方法
  3. python判断txt文件是否为空_Python中的空值怎么判断
  4. js获取被点击的元素以及子元素
  5. macOS zip 打包加密和 unzip 解压
  6. 自定义报表预览控制工具条
  7. bmp180气压传感器工作原理_陕西压力传感器的工作原理信息推荐
  8. 动态规划求解所有字符的组合数
  9. 计算二叉树的叶子结点个数_C++数据结构二叉树统计总结点个数,叶子结点个数,单分支结点个数,双分支结点个数。...
  10. ​每一页都是知识点,这本Flutter企业级实践指南太绝了
  11. 用C#实现文件夹拷贝
  12. ubuntu14.4安装GTK\opencv和pythoy opencv
  13. html5 绘制思维导图,Qunee组件制作思维导图
  14. JWT实现接口双重认证,提供安全又不复杂的接口安全能力
  15. php 展示微信图片尺寸,微信公众平台图片最大尺寸
  16. linux swap空间不足,swap空间不足问题解决
  17. android中实现微信九宫格,微信小程序九宫格布局
  18. python 颜色与字体
  19. GraphicsMagick创建空白图片
  20. ettercap局域网DNS欺骗实现过程

热门文章

  1. matlab 二值化_MATLAB实验,图像二值化处理
  2. 当前主要使用的python版本_如何获取当前使用的Python版本信息?(代码示例)
  3. brave浏览器_兼容Chrome 插件的Brave浏览器,带给你更快速的上网冲浪体验
  4. appcontroller.php,php用什么开发app接口
  5. Android SDK Tools Setup 提示 “ java se development kit not found”
  6. 提高ActiveMQ工作性能
  7. python调用脚本或shell的方式
  8. 添加时间数据时 出现多一天或者少一天的问题 解决方案
  9. hadoop错误,重新格式化namenode后,出现java.io.IOException Incompatible clusterIDs
  10. redis的导入导出需要特别注意的地方