面向对象编程的概念和原理

面向对象编程的概念和原理

目标

  • 掌握面向对象范例与结构化编程范例的区别
  • 了解对象的关键特征
  • 了解面向对象编程 (OOP) 的定义原则带来的好处

什么是对象?

Java 语言(基本上)是面向对象的。本单元使用结构化编程作为对比基础,简要介绍 OOP 语言的概念和原理。

面向对象的语言遵循的编程模式不同于结构化编程语言,比如 C 和 COBOL。结构化编程范例是高度面向数据的:您拥有数据结构,然后程序指令处理该数据。面向对象的语言(比如 Java 语言)将数据和程序指令组合到对象 中。

对象是一个自成一体的实体,它仅包含属性和行为,不含任何其他内容。不需要拥有包含字段(属性)的数据结构并将该结构传递到处理它(行为)的所有程序逻辑,在面向对象的语言中,数据和程序逻辑组合在一起。这种组合可在显著不同的粒度级别上执行,从细粒度对象(比如 Number)到粗粒度对象(比如一个大型银行应用程序中的 FundsTransfer 服务)。

父和子对象

父对象 用作派生更复杂的子对象 的结构基础。子对象看起来像它的父对象,但更加特殊化。在面向对象的范例中,可以重用父对象的通用属性和行为,向它的子对象添加不同的属性和行为。

对象通信和协调

对象通过发送消息(在 Java 用语中称为方法调用)来与其他对象通信。而且,在面向对象的应用程序中,程序代码协调对象之间的活动,以在特定应用程序域的上下文内执行任务。

对象摘要

一个精心编写的对象:

拥有明确定义的边界 执行一组有限的活动 仅知道它的数据和它完成活动所需的任何其他对象 在本质上,对象是一个离散的实体,它仅包含执行其任务而必要的对其他对象的依赖关系。

是时候看看 Java 对象是什么样子了。

示例:person 对象

我首先介绍一个基于一种常见的应用程序开发场景的示例:一个由 Person 对象表示的人。

从对象的定义可以知道,一个对象有两个主要元素:属性和行为。下面展示了这些元素如何应用到 Person 对象。

作为一条经验规则,可将对象的属性视为名词,将行为视为动词。

属性(名词)

一个人可能有哪些属性?一些常见的属性包括:

  • 姓名
  • 年龄
  • 身高
  • 体重
  • 眼睛颜色
  • 性别

您可能会想到更多(而且您始终可以在以后添加更多属性),但此列表是一个不错的开端。

行为(动词)

一个真实的人可以做各种各样的事,但对象行为通常与某种应用程序上下文相关。举例而言,在业务应用程序上下文中,您可能想询问您的 Person 对象,“您的身体质量指数 (BMI) 是多少?”作为响应,Person 将使用它的身高和体重属性的值来计算 BMI。

Person 对象背后可能隐藏着更复杂的逻辑,不过我们暂时假设 Person 具有以下行为:

  • 计算 BMI
  • 打印所有属性

状态和字符串

状态 是 OOP 中的一个重要概念。对象的状态在任何时刻都由它的属性值来表示。

对于 Person,它的状态由姓名、年龄、身高和体重等属性来定义。如果想提供多个属性,可使用 String 类来完成,稍后将更详细地介绍该类。

结合使用状态和字符串的概念,可以对 Person 说,“通过向我提供您的属性列表(或 String)来告诉我您是谁。”

OOP 的原则

如果您有结构化编程的背景,您可能还不清楚 OOP 的价值优势。毕竟,一个人的属性和检索(并转换)这些值的任何逻辑都可使用 C 或 COBOL 编写。如果理解了它的定义原则,OOP 范例的优势就会更加明显:封装、继承 和多态性。

封装

回想一下,一个对象是离散的或独立的。此特征是封装 的工作原理。隐藏 是另一个有时用于表达对象的独立、受保护性质的术语。

无论使用哪个术语,重要的是对象在它的状态和行为与外部世界之间保持一条界线。像真实世界中的物体一样,计算机编程中使用的对象与使用它们的应用程序中的不同对象类别拥有各种各样的关系。

在 Java 平台上,可以使用访问修饰符(后面将会介绍)来区分公共 与私有 对象关系的性质。公共访问是完全开放的,而私有访问意味着对象的属性仅可在对象自身内访问。

公共/私有边界采取面向对象的封装原则。在 Java 平台上,可以逐个对象地改变该边界的强度。封装是 Java 语言的一个强大特性。

继承

在结构化编程中,常常会复制一个结构,为它提供一个新名称,然后添加或修改属性,使新实体(比如一个 Account 记录)不同于它的原始来源。随着时间的推移,此方法会生成大量重复代码,这可能带来维护问题。

OOP 引入了继承 的概念,使得特殊化的类 — 无需额外的代码 — 可以 “复制” 它们要特殊化的来源类的属性和行为。如果其中一些属性或行为需要更改,您可覆盖它们。您更改的唯一的源代码是创建特殊化的类所需的代码。来源对象称为父对象,新的特殊化对象称为子对象— 我们已介绍过这些术语。

假设您在编写一个人力资源应用程序并想使用 Person 类作为一个名为 Employee 的新类的基础(也称为超类)。作为Person 的子类,Employee 将拥有 Person 类的所有属性,以及更多属性,比如:

  • 纳税人识别编号
  • 员工编号
  • 工资

继承使得创建新 Employee 类很容易,不需要手动复制所有 Person 代码。

多态性

多态性是一种比封装和继承更难掌握的概念。在本质上,多态性表示属于一个分层结构的同一个分支的对象,在发送相同的消息时(也即在被告知执行同一件事时),可通过不同方式表现出该行为。

要了解多态性如何应用到业务应用程序上下文,可返回查看 Person 示例。还记得告诉 Person 将它的属性格式化到一个 String 中吗?多态性使 Person 可以依据它的 Person 类型,以各种不同的方式表示它的属性。

多态性是您将在 Java 平台上的 OOP 中遇到的更复杂概念之一,不属于这个入门课程的介绍范畴。后续单元将更深入地探索封装和继承。

不是一种单纯的面向对象语言

有两种性质可区分 Java 语言与单纯的面向对象语言(比如 Smalltalk)。首先,Java 语言是对象和 原语类型的一种混合。其次,使用 Java,您可编写代码来将一个对象的内部情况向任何其他使用它的对象公开。

Java 语言为您提供了必要的工具来遵循合理的 OOP 原则,生成合理的面向对象代码。因为 Java 不是单纯面向对象的,您必须在编写代码的方式上运用一些规则— 该语言不会强制要求您执行正确的操作,所以您必须依靠自己。

上一篇 下一篇