程序设计基础知识以及浅谈面向对象的概念


一、程序设计基础

1. 什么是程序

程序(program)有时也被称为应用(application),是让芯片、硬盘等硬件(hardware)逐条执行的一系列指令的统称。软件(software)是由程序和程序使用的数据组成的。程序由具体的程序设计语言(programming language)编写,这些语言用特殊的语句和符号表述问题解决方案,它们有特定的语法规则,明确地告诉程序员如何能将语言的这些单词和符号组成程序语句,这些语句就是程序运行时要执行的指令。

计算机系统是由软件和硬件一起组成的可用来解决问题的工具。

现在假设你编写一个产品的使用步骤说明书,无论你用英语、德语还是中文中的任何一种语言来编写,产品的使用步骤其实都是相同的,但不同语言的表达方式是不同的,所以需要产品的操作者熟悉说明书所使用的语言,才能够理解和执行使用方法。类似的,你可以从众多的程序设计语言如Java、C++、Pascal等中选择一种来编写程序解决方案,不论你使用哪种语言,程序的目的本质上是一样的。

计算机必须要理解你所编写的指令才能去执行它们,所以程序最终必须要翻译成计算机能够执行的形式,即机器语言(machine language)。
不同的CPU有不同的机器语言,例如我们不能将专为Sparc处理器的Sun工作站而编写的程序直接放到安装Intel处理器的Dell PC上运行。

2. 程序设计语言

机器语言代码表示为一串二进制数,可见对人类而言是非常难读且难写的,最初的程序通过开关或一些类似的枯燥方式送入计算机,这样的技术非常费时且容易出错。种种问题促使了汇编语言(assembly language)的诞生。它使用助记符取代了二进制位,这些助记符很像是较短的英文单词,用他们表示命令或数据。一般情况下,每条汇编语言指令只完成一个简单的操作,所以对程序员而言依然是难用的。因此汇编语言和机器语言都被看作是底层语言,也被称为低级语言(low-level language)。

如今大多数程序员都采用高级语言(high-level language)来编写程序。高级语言使用类似于英语的短语来表示,所谓高级就是它的表达方式远不同于最终执行的机器语言。一条高级语言可能等价于许多条乃至上百条机器语言指令,能够让程序员忽略机器语言的细节,更加易于阅读和编写。

有些程序设计语言的运行方式被认为是比高级语言的等级还高。它们可能包含一些特定的工具,可以自动生成报告或是与数据库进行交互。这些语言称为第四代语言(fourth-generation language),因为它们是跟在机器语言、汇编语言和高级语言这前三代计算机程序设计语言之后出现的。

计算机结构的层次模型

3. 编辑、编译和解释程序

编辑器(editor)用于将程序键入到计算机并保存在一个文件中。熟悉编辑器的使用会极大地提高程序员键入程序及修改程序的速度。在编辑并保存了程序之后,要将它从高级语言转换成可执行的形式。编译程序(compiler)可将一种语言的代码转换为等效的另一种语言代码。原来的代码称为源代码(source code),转换后的代码称为目标语言(target language)。许多传统的编译程序将源代码直接转为具体的机器语言,这样一个给定程序的转换过程只需要一次,而且得到的可执行程序在需要的任何时候都可以运行。解释程序(interpreter)类似于编译程序但有着一个很大的区别:它兼有转换和运行的功能。它可以转换并执行源代码中的一部分例如一条语句,然后再转换并执行一条语句,以此类推。这样的好处是省去了一个独立的编译过程,但是程序运行的速度相对会变慢,因为每次运行都要进行转换的过程。

以Java转换及运行的过程举例,它合并了编译程序和解释程序的功能。Java编译程序将Java源代码转换为Java字节码(bytecode)字节码使用类似机器语言代码的底层格式来表示程序。Java解释程序读入Java字节码并在具体的机器上运行,而字节码编译程序可以将Java字节码转换为具体的机器语言以获得在机器上的高效运行效率。

Java字节码不依赖于任何具体的处理器类型,它使得Java语言具有体系结构中立的好处,所以Java程序很容易从一种机器移植到另一种机器上。唯一的限制是,在要运行Java字节码的机器上,必须有对应于处理器的Java解释器或字节码编译程序。

Java程序的运行过程

4. 错误

人们常用计算机错误(computer error)这一术语来描述开发程序过程中遇到的错误状况,这种解释被看作是偏颇的。例如,假设你的信用卡里有一项收费是15元,但当你拿到账单时却这项收费被标成了150元。信用卡公司为所谓的“计算机错误”道歉,那么是计算机武断地在数的后面加了个零,还是将这个数乘上了10呢?当然都不是,计算机只会按照我们给它的命令来执行,并对我们提供的数据进行操作。如果我们的程序是错误的,或者我们的数据不够精确,就不用去期望计算机给出正确的操作结果了。错误本质上是一种乱输入,乱输出(garbage in,garbage out)。

开发程序时的错误一般分为三类:

  • 编译时错误(compile-time error)
  • 运行时错误(run-time error)
  • 逻辑错误(logical error)

如果任何一条语句不符合语言的语法规则,或者程序员想做的事情是在语义层面上所不允许的,编译程序时都将指出错误,并且不能生成字节码和可执行程序。当运行时要进行的操作时不确定的,系统就只能放弃继续处理相关程序。例如当出现零作为运算的除数时,程序将会“崩溃”并且中断。逻辑错误出现时,软件编译和运行时都没有问题,但是却得到不正确的结果。例如对值进行不正确的计算或者图形按钮没有出现在正确的位置。程序员必须对程序进行彻底测试,发现错误时必须跟踪程序的源代码,并将其修改正确,这一过程称为调试(debugging)

在Java中,许多运行时错误称为“异常”,能将其捕获并进行处理。

5. 软件开发

软件的创建过程不仅仅只是编写代码。编辑及运行程序是必要的步骤,但软件开发的核心是问题求解(problem solving)。我们编写程序是为了解决具体的问题。
一般情况下,问题求解包含以下几个步骤:

  1. 理解问题
  2. 设计方案
  3. 考虑方案的选择并优化方案
  4. 实现方案
  5. 测试方案并修改存在的问题

对应的,任何的软件开发工作都包含四个基本的开发行为:

  1. 建立需求
  2. 生成设计
  3. 实现设计
  4. 测试

软件开发的生命周期


二、面向对象概述

面向对象程序设计方法广为流行,如今已经成为商业软件开发中的主流方法。它最大的特点是可以非常有效地使用对象来表示真实世界中的实体,让我们将程序与程序所表达的真实情况对应起来,从而更加容易地去解决问题。

1. 对象的基本概念

对象是程序中的基本元素,软件对象通常表示问题域中的一个真实对象。每个对象都有一个状态(state)和一组行为(behavier)。状态是指所处的现状,定义了对象当前的基本特征;对象的行为则是与对象相关的活动。例如某个银行账户目前是负债的状态,那么它就无法进行取款的行为。一个对象的属性(attribute)是指它内部保存的值,可以用基本数据(如数值或字符)或其他对象来表示。例如银行账户对象可以保存用于表示账户余额的一个浮点数,以及所有者的姓名等。方法(method)是有自己名字的一组程序设计语句,当调用方法时,就执行它的语句。方法与对象相关,一个对象的方法定义了它的潜在行为。例如定义银行存款行为,就可以定义一个方法,其中的语句将根据存多少来更新账户的余额。

对象全体属性的值定义了它当前的状态,每个对象都有由其属性定义的一个状态以及由其方法定义的一组行为。

2. 类与对象

对象由(class)来定义。类是对象的蓝图。一旦定义了类,就可以创建这个类的多个对象。房屋的设计图定义了房子的重要特征——墙、窗户、门等等。一旦有了这个设计图,就可以在不同的地点、为不同的人、搭配不同的装修风格来建造好几幢房子。这些房子有着一些相同的特征,如果要建一幢房型不一样的房子,就需要一张不同的设计图。

类与对象的关系最多就像设计图与房子的关系一样。一般情况下,类中没有包含用来存储数据的空间,而每个对象有自己的数据空间,这正是每个对象可以保存自己状态的原因。

类与对象

对象应该是封装(encapsulate)的,它保护并管理自己的信息。对象状态的唯一修改方式应该是通过对象的方法来完成的,而不允许使用对象的代码(对象的客户)直接访问变量。

对象应该与系统的其他部分分隔开来,它只能通过特定的方法与程序的其他部分进行交互。这些方法定义了对象与使用它的其他对象之间的接口(interface)。

通过继承(inheritance)机制,可从其他的类来创建新类,也就是说一个类的定义可以基于已有的另一个类。利用我们想创建的不同类之间的相似之处,一个类可以用来派生几个新的类,派生类也可以用来派生更多的类,一个类中定义的属性和方法由它的子类继承,然后又依次传给子类的子类,这样形成了类的层次。公共的特征定义在最高层的类中,特殊的、不同的特征定义在派生的类中。

类的继承

除了继承,不同的类之间还有两种常见的关系是依赖聚合。一个类的方法调用其他类的方法,这种机制建立了“使用”关系。例如类A的一个或多个方法调用类B的一个或多个方法,如果被调用的方法是静态的,则类A只能通过名字来引用类B的方法。如果被调用的方法不是静态的,则类A必须能访问类B的某个实例,以便能调用这个方法,即类A必须有一个指向类B对象的引用。一般情况下,我们总是尽量让类之间的依赖关系最低,类之间的依赖越少,系统中互相影响的情况就越少,因此错误就越少。有些情况下,一个类依赖于它自己,即一个类的对象与同一类的其他对象进行交互,要实现这一点可以让类的方法接收本类的一个对象作为该方法的参数。

有些对象是由其他对象组成的。例如一辆汽车是由发动机、底盘、车轮和其他一些部件组成的,每个部件都可以看成是一个独立的对象。这样汽车就是一个聚合(aggregation)对象,是由(或部分是由)其他对象组成,可以描述为has-a(有一个)关系,例如一辆汽车有一个底盘。聚合是一类特殊的依赖关系。可以说成是:由另一个类部分地定义的一个类依赖于定义它的那个类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

成名在望xy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值