过程化编程
一个程序由一个或多个过程组成。过程就是一个模块或者函数所执行的一个具体任务,例如读取来自用户的输入信息、执行计算、从文件读写信息、显示输出等等。
通常,过程所处理的数据都是和过程分离的。在过程化编程中,数据通常从一个过程(函数或者模块)传到另一个过程(函数或模块)中。重点是创建过程为中心,处理程序的数据。
面向对象编程
面向对象是以创建对象为中心。一个对象是一个软件实体,它包含数据和过程。
- 包含在一个对象中的数据称为该对象的字段。一个对象的字段(数据)只是存储在该对象中的变量、数组、其他数据结构。
- 一个对象所执行的过程称为方法,一个对象的方法只不过是模块和函数。每个方法操作一个或多个字段(数据)
面向对象(OOP)通过封装和数据隐藏来解决代码和数据的分离问题。
- 封装是指将代码和数据结合在于给单独的对象中
- 数据隐藏是指一个对象的能力,它使该对象之外的代码看不到该对象的数据。(无法直接调用数据,需要通过调用方法间接调用。)
- 对象的方法提供了在对象之外间接访问(调用)该对象中数据的编程语句。
当一个程序员改变一个对象的内部数据结构时,他也修改对象的方法,以便他们可以正确的操作数据。
然而,外部代码与方法的交互方式不会改变。
类
OOP(面向对象编程)中,对象不是独立的程序,而是因其提供的服务而满足了程序的需要。可以被直接重复性使用。
类是一组代码,他为一个特定的对象指定字段和方法。一个对象被创建之前,必须由程序员设计,该程序员确定必要的字段和方法,然后创建一个类。
将类看作创建对象的“蓝图”。它与一座房子的蓝图功能相似。蓝图本身不是房子,但是它详细描述了一座房子。当用蓝图建造一座实际的房子时,我们可以说我们正在建造一个由蓝图所描述的房子的实例。如果愿意,我们可以建造多个单独的房子实例。
类不是一个对象,而是一个对象的描述。从一个类创建的每一个对象都称为该类的一个实例。每一个实例都由该类所描述的字段和方法。
在大多数的OOP中,访问说明符(access specifier)指定一个类的字段或者方法的访问方式。包含:
- private、protect、public三种
New关键字在内存创建一个对象过程图
当一个变量被赋值一个对象的地址时,就可以说该变量引用该对象。
从类的字段取值而不更改其值的方法称为访问器方法(access method)。一个方法向一个字段存储一个值或者以其他方式更改一个字段中的值,这种方法称为修改器方法(mutator method).
构造函数:是一种在创建对象时被自动调用的方法。多数编程语言中,构造函数和所在的类具有相同的名字。
寻找一个问题中的类及其功能
重点聚焦1:寻找一个问题中的类
一种简单而流行的技术包括一下步骤:
- 对问题领域进行书面描述
问题域是与问题相关的真实对象、团体和重要事件的集合。一个问题域描述应包括如下内容:- 物理对象:如车辆、机器、产品
- 人的角色:如经理、员工、客户、学生、教师、管理员等
- 商业活动的结果:如客户订单、服务报价等
- 记录项目:如客户履历、工资记录等
- 在描述中识别所有名词(包括代词、名词短语),每个名词都是潜在的类。
识别所有的名词和名词短语,一些名词有重复,注意去除。然后优化名词,使得仅仅包括当前要解决的特定问题所必须的类。 - 对列表进行优化,使其仅仅包含问题相关的类。
将一个名词从潜在类的候选列表中消除的原因理由:- 有些名字意思相同,表示的是同一个事物,仅保留一项
- 有些名词所代表的项在我们要解决的问题中可能并不代表我们关心的项。当我们应用程序中不需要处理和某些少量名词相关的信息时,可以进行剔除。
- 有些名词所代表的是对象,而不是类。描述特定事物的名词。只是类的一个实例。
- 有一些名词可以表示存储在一个常规变量中的简单值,不需要一个类。一个类包含字段和方法。如果一个名词不代表具有任何可识别的字段或者方法的项,那么多半可以删除。为了帮助确定一个名词时候代表具有字段和方法的项,可以考虑一下问题:
- 是否要用一组相关的值来表示项目的状态?
- 项目是否实施明显的操作?
如果对这俩个问题的答案都是否定的,那么多半可以用一个常规变量存储。
重点聚焦2:定义类的功能
在上一个重点聚焦中我们对问题域进行了描述,并且还得到了需要的类,下一步,需要确定这些类的职责。一个类的职责如下:
- 类所需要了解的信息
- 类所负责执行的操作
当你确定了一个类所负责了解的信息时,你已经确定了要存储在字段中的值。同样,当你确定一个类所负责执行的操作时,你已经确定了类的方法。
问下面两个问题对类的构建通常是有帮助的:
- 在这个程序中,类的一个对象需要知道什么?
- 类必须做什么?
寻找答案的第一步是描述问题域。在这里一个类必须了解和做的许多事情将会被描述出来。但是,一些类的功能可能不会在问题域中直接提出,所有经常需要集思广益。但是在这一点上容易出现一个错误,那就是把一个对象应该知道的事情交给了类。
避免过时数据:当一个类的项的值取决于其他类字段时,当其他字段改变时该项没改变更新,是会出现数据过时的,所以不能直接存储在字段中,应该使用类的方法实时更新,利用方法函数计算结果然后返回值的方法。
类的继承
继承和“是一类”的关系
当一个对象是另一个对象的特殊版时,它们之间有一种“是一类”的关系。这意味着特殊对象不仅具有一般对象的所有特征,还具有使其成为特殊对象的其他特征。
继承涉及一个超类(基类)(superclass)和一个子类(派生类)(subclass)。超类是普通类,子类是特殊类。
类的多态
多态性可以在不同的类中创建具有相同名字的方法,并且可以根据对象的类型来调用正确的方法。
多态性的基本要素:
- 可以在超类中定义一个方法,然后在子类中定义一个名称相同的方法,当子类方法与超类方法具有相同的名称时,通常说子类方法覆盖超类方法。
- 可以声明一个超类的类变量,然后使用该变量引用超类或子类的对象。
模块和函数
- 模块
模块是程序中的一组语句,用以执行具体的任务。大多数程序所执行的任务一般都很大,需要分解成几个子任务,即几个小模块,每个模块执行这个任务的一个具体部分(分解后的小任务)。
模块一般称为过程、子例程、子程序、方法和函数,函数一种特殊类型的模块。
当调用一个模块时,计算机就跳到哪个模块,执行模块体的语句。当执行到模块结束行时,计算机返回程序中的模块调用处,程序从那一处继续执行。 - 函数
函数是一个具有返回值的模块,返回值传给程序中调用模块之处。返回值可以像任何其他值一样使用:它可以赋值给一个变量、显示在屏幕上、用于数学表达式等等。
参考:
[1] 程序设计基础:原书第3版[M].(美) 托尼 加迪斯(Tony Gaddis)著;王立柱,刘俊飞译.2018.04