第一章 什么是面向对象编程

来源:互联网 发布:js压缩代码还原 编辑:程序博客网 时间:2024/05/22 04:27

这里写图片描述


这里写图片描述


☺ 在面向对象编程中, 重点是正在被操作的数据, 而不是实现这些操作的过程(函数), 而且,数据和操作不像以前那样被当作彼此孤立的实体, 现在它们被看做是一个整体, 数据带有一组操作, 允许用户对数据执行一些有意义的操作,同时, 任何外部程序或函数无法直接访问数据本身, 那么修改该类中的数据唯一的方法就是使用为修改数据而提供的操作, 这些操作为修改数据的行为,

注意: 面向对象编程就是类的实例构成程序的编程方法,而且, 多个类之间可以通过继承关系相互关联。

☺ 在面向对象编程中, 关键要理解类和对象的概念, 类是一个实体, 它拥有一组对象的共同属性(特性), 对象是类的实例, 类的所有对象都具有相同的结构(数据)和行为。

☺ 类决定了创建对象的大小和行为, 在面向对象的解决方案中,一切皆为类的对象, 这样看来, 在面向对象编程中, 我们只需考虑类和对象、类之间的关系,以及对象之间的关系

☺ 注意: 功能分解按顺序提出了系统设计中的三要素(算法 控制流和数据描述),而在OOP中, 此三要素的顺序完全相反,

☺ 只有在类内部声明的操作, 才能访问私有成员,类的外部无法使用私有成员, 我们将这种私有数据称为被封装的数据, 以这种方式隐藏在类的内部称为数据封装

☺ 每个类对象都有相同的数据和行为, 那么可以通过类的任意对象使用类中的任何操作, 那么同时所有对象都有自己的私有数据副本, 各对象之间的差别取决于保存在私有数据中的值

☺ 对象是类的实例, 类仅在程序的源代码中可见, 而对象则参与到程序的运行中, 它是类的活实例, 对象占据内存空间, 我们可以感受到对象的存在, 创建类对象的过程称为实例化对象

☺ 在面向过程编程中,我们总是讨论调用过程, 比如: 调用某某函数,来谈论问题, 但是,在OOP中, 函数通过对象调用。


(2) 术语


这里写图片描述


这里写图片描述
这里写图片描述
这里写图片描述


(3)什么可以作为类


● 难点在于如何为给定的问题找出合适的类, 我们必须理解类代表什么, 何时将问题中的某些部分转化为类, 而非数据, 反之亦然, 根据我们的定义, 类拥有一组对象的共同属性(或者特性)。 怎样的共同才是共同?

● 当我们决定创建一个类时, 第一个问题就是“是否确实需要这个类的多个实例?”, 如果答案为“是”, 那么我们的方法就可能正确——至少粗略看起来正确。 如果发现类的实例之间没有差别(也就是说, 每个实例和其他实例相同, 而且他们的行为完全一致),那么我们可能错误地创建了这个类, 应该将这个类创建为一个值

● 不可能一次设计就能一步到位, 在第一轮设计中作为类的部分, 可能在第二轮设计中改为数据, 反之亦然, 解决问题的方案在不断变化, 最终的解决方案很可能与最初的设计截然不同

● 这都源于类的重要特性, 类不只是容器, 不能认为它仅仅用于存储被函数修改的数据, 类不只是将它的各个部分简单地组合起来而已, 类决定如何完成任务, 它清楚地陈述了该类的对象可以做什么


(4) 什么不是类


● 让所有数据成为私有数据, 然后添加一组函数来获得和设置数据成员, 这不是类, 类不只是一组允许客户获取和设置数据成员值得函数, 数据封装隐藏了类中的数据, 而且通过成员函数提供更高层次的抽象。 如果只是让函数读写结构中的数据, 其实并未简化任何东西, 只包含获值函数(getter)和设值函数(setter) 的类是糟糕的设计


(5)类的目的


● 设计类的目的必须非常明确, 一个优秀的类应该易于理解和使用,必须清楚地向客户说明其目的

● 类必须简明扼要地说明它的功能和局限性, 如果在查看类之后, 客户仍然不解其用途, 则说明类的设计很糟糕, 而且很可能是错误的, 需要重新设计

● 一个标准是类中成员函数的数量,设计优秀的类所包含的成员函数应该介于 15~25个


(6))深入了解对象


● 对象知道如何修改和维护它的数据成员

● 区别类和对象是一个逻辑问题, 简单地说, 对象是带有状态和行为的活的实体, 所有类对象的行为都定义在类中, 而状态则由对象单独维护


(7) 对象的状态的重要性


● 属性是每个对象的静态性质,数据成员的值是一个动态的值, 对象的状态是所有静态性质以及这些静态性质的动态值的集合

● 一个设计良好的类的实现不应该允许客户直接访问对象的数据成员, 数据成员只能由成员函数修改, 而客户只能呢个通过操作对象来使用成员函数


(8) 谁控制对象的状态


● 对象的状态通过成员函数来修改,然而,并不是所有的成员函数都可以修改对象的状态——一些成员函数仅允许使用状态中的值,

● 类中的每一个方法都会对对象的状态进行一定程度的假定,而且, 类假定无法从外部修改对象的状态——只有在成员函数内才能修改对象的状态。 成员函数非常了解用对象的状态值可以做什么,也非常清楚如何改变对象的状态值, 正是成员函数控制了对象的状态。

● 注意: 成员函数代表客户执行操作,这点很重要, 客户调用一个操作(即向对象发送请求),操作便完成一些有意义的工作, 通常, 方法由客户启动, 它不会自己执行

● 吗,没有任何数据成员的类(不是抽象基类)是糟糕的设计, 它说明该类创建的对象没有任何状态


(9)对象的状态


● 对象的行为在某种方式上是对客户调用消息的响应。 行为是对象对消息采取的行动和做出反应, 消息会引起状态的变化, 也会引起发送更多的消息至其他对象,或两者兼之, 当客户向对象发送消息时, 为了完成操作, 该对象可能向另一个对象发送其他消息


(10) 面向对象软件开发的阶段



(10.1 面向对象分析(OOA))


● 软件工程不是从研究一组类或对象开始的。 我们从简单描述问题开始(大多数都不完整), 这是面向对象软件开发过程的起点。 在这一阶段, 我们要找到合适的类。

注意: 为了提供良好的解决方案, 大多数复杂的问题需要的不止是一个类, 而是许多类。 一组类可以互相通信、合作和协作, 已完成最终的目标。

● 面向对象分析涉及从类和对象的角度分析问题, 这些类和对象都要从问题领域中找出。但是, 这些类并不是在最终实现中能直接使用的类

● 本阶段的任务主要是, 彻底地分析问题和明确地指定要求。 要在客户的问题领域中找出类和对象, 并用其完整地描述什么方案可行, 什么方案不可行, 换言之, 我们应采用客户能够理解的类和对象来描述问题, 这些类和对象都可以直接在问题领域中找到

说明: 问题领域就是问题所属的区域或部门。

● 要解决任何与现实相关的问题, 都需要领域专家和面向对象软件专家的密切合作。

● 注意: 在OOA 阶段中, 我们应该将注意力放在问题领域中使用的类。 实现的细节将在面向对象设计阶段实现。

● 在软件开发过程中, 就涉及为问题领域中已知地对象建模, 我们可以将现实生活中了解的对象映射到问题解决方案的逻辑视图中


(10.2 面向对象设计(OOD))


● OOD(面向对象设计)阶段在OOA(面向对象分析)阶段之后, 在本阶段中, 我们将在OOA 阶段开发的框架中加入细节, 待解决的问题将被分解为类和对象用于实现中

● 本阶段要完成的任务包括 定义类之间的关系、 描述对象如何才能适应系统的进程模型、如何跨地址空间划分对象,系统如何完成动态行为等。

● 对于较简单的问题, 设计人员通过将名次作为类, 将动词作为这些类的方法,即可获得关于类的线索。 但是,在用语言描述此问题时, 却很容易将名词和动词的角色完全颠倒。 因此, 通过这种途径获得类的线索, 在探索过程中仅做参考。

● OOA和OOD 都遵循一些现有的设计方法论。 方法论 使用一些表示法来表示类、 对象以及它们之间的关系。

● 注意:仅学习一种设计方法论并不能成为OOD专家。 方法论只是一种用于表达设计思想的工具, 它能让其他人更好地理解使用者的想法和思路。 方法论可以在设计过程中提供帮助, 但是对发现类和实现类却无能为力, 设计小组成员的知识和经验是无可取代的

● OOA和OOD 都不是C++ 语言所特有的, 它们是解决任何面向对象问题的基本方法。


10.3 面向对象编程(OOP)


● 这是面向对象软件开发环节的最后一个阶段,将OOD阶段的成果输出, 将其输入至OOP 阶段中, 这个阶段, 将用选定(或根据项目要求指定) 的语言编写真正的代码 如前所述, 面向对象编程是一种由合作对象(就是类的实例) 构成程序的编程方法, 可通过继承关系设计出相关联的类。


(10.3.1 对象模型的关键要素)


● 在我们讨论的问题解决方案中, 建立对象模型的关键要素是:

数据抽象封装层次

● 数据抽象是为了强调对象的相似性, 忽略其差异性来定义类。 在表现类(抽象) 的主要特性时, 应避免展现那些不重要的和分散注意力的要素。 实际上, 类就是一个抽象, 顺带一提, 抽象将重点放在对象的外部视图中, 并将对象必不可少的行为从内部的实现细节中分离出来。

● 封装(或信息隐藏) 是为了隐藏抽象的内部实现细节。 它将抽象的外部接口从内部实现细节中分离出来。 封装和抽象彼此互补。 一个设计良好的抽象会封装一些成员, 而被封装的实体则帮助抽象保持完整性。 需要注意的是: 抽象先于封装。 另外, 只有在开始实现时, 才应该将注意力放在封装上。

这里写图片描述


(11) 面向对象编程语言的要求


● 任何声称支持面向对象编程的语言都必须提供易于设计和实现的特性:

数据抽象封装继承

● 所谓“易于” 指的是抽象和封装必须自然而然, 不需要程序员在这上面花太多的功夫

这里写图片描述

● 对于OOP, 继承是另一项非常重要的特性。 不支持继承的语言不能成为面向对象编程语言。 某些语言支持数据抽象和封装, 但并不支持任何形式的继承。 这样的语言不是面向对象编程语言, 它们被称为 基于对象语言, 虽然可以实现对象, 但是, 却无法通过继承扩展它们,

注意: 任何面向对象语言都是基于对象语言

注意: 继承是区别基于对象语言和面向对象语言的关键特性


(12) 对象模型的优点


● 简单类的复用, 如复用日期、时间、分数等, 很大程序上促进了代码复用和避免重复的代码。 简单的类也可用于创建较复杂的类, 达到更高程度的代码复用。