一、面向对象技术概论(上)

面向对象理论很早就被提出了,但它真正地渗透到软件开发的各个领域,并且在软件开发实践中大规模应用,却要等到上世纪九十年代。到目前为止,面向对象技术已是软件开发的主流,全面取代了结构化编程技术曾经具有的地位。

面向对象技术与结构化编程技术有着不同的风格,但同时也有着密切的联系。从具体编程角度来看,面向对象技术与结构化编程技术很难截然分开,两者的根本差别在于思维方式。

要了解面向对象技术,得从结构化编程技术入手。

1.1、结构化编程引例 

结构化编程在上世纪七十年代兴起,由于它具有很多的优点,出现之后没几年就占据了软件开发的主流,大家熟悉的C语言就是一种典型的结构化编程语言。

结构化编程的基本方法是“功能分解法”,具体来说,就是将要解决的实际问题进行分解,把一个大问题分成若干个子问题,每个子问题又可以被分解为更小的问题,直到得到的子问题可以用一个函数来实现为止。

我们先从一个简单的编程任务开始,逐步体会结构化编程与面向对象编程的不同风格。请看以下的这道编程题目:

请编程计算出1999年5月10日到2006年3月8日期间一共有多少天?

这是一个简单的算术问题,尽管如此,为了做个铺垫,我们还是把计算方法再叙述一下,以帮助读者理清思路。

有以下注意事项:

①、一年有365天,但闰年有366天;

②、一年有12个月,大月31天,小月30天;

③、2月最特殊,普通年份28天,闰年29天。

综上所述,计算步骤如下:

(1)计算从1999到2006期间一共有多少个整年:

2000、2001、2002、2003、2004、2005,共有6个整年,其中2000和2004年是闰年,因此,共有6*365+2=2192天。

(2)计算从1999年5月10日到年底(即12月31日)共有多少天:

5月10日到12月31日中共有4个整的大月(7、8、10、12月),三个整的小月(6、9、11月),共计4*31+3*30=214天。

5月10日到月底(31日)还有31-10=21天。

所以,1999年5月10日到年底共有214+21=235天。

(3)计算从2006年1月1日到2006年3月8日期间一共有多少天:

1月有31天,2006年不是闰年,2月有28天,所以,总共有31+28+8=67天。

综上所述,1999年5月10日到2006年3月8日期间一共有2192+235+67=2494天。

事实上,上述计算过程其实就是一个计算机算法,由于步骤很明确,可以很容易地将这一过程转为程序。

编程之前,先将实际问题抽象为以下模型:

输入:两个日期 => 程序 => 输出:两个日期间的天数

我们要完成的工作就是开发出这样一个程序:程序接收两个日期值,经过计算之后,输出这两个日期之间的天数。

(1)结构化分析过程 

为了清晰地表达出程序需要处理的信息,先定义一个结构体类型:

结构体类型MyDate其实是定义了一种数据结构。我们正是在这个数据结构之上构建出整个程序的。

对模型进行结构化分析的第一步,是将“程序”完成的功能转化为由一个函数CalculateDaysOfTwoDate()实现:

//计算两个日期中的整天数

static int CalculateDaysOfTwoDate(MyDate beginDate, MyDate endDate)
{
   //……
}

余下的开发工作体现为给CalculateDaysOfTwoDate()编写代码实现日期计算的功能。

在结构化编程中,有这样一个重要的公式:

程序=数据结构+算法

数据结构代表了要处理的信息,而算法则表明要对这些信息进行哪些处理工作。

只要确定了数据结构和算法,一个程序就成型了。因此,将程序中要处理的数据抽象为某种数据结构是结构化编程的基础。

在本例中,算法非常简单,可以直接将人计算过程中的每一个步骤转为一个函数,由此得到以下两个函数:

//计算两年之间的整年天数,不足一年的去掉

static int CalculateDaysOfTwoYear(int beginYear, int endYear)
{
     //……
}

//根据两个日期,计算出这两个日期之间的天数,不理会中间的整年

static int CalculateDaysOfTwoMonth(MyDate beginDate, MyDate endDate)
{
     //……
}

第一个函数根据两个年份之间的整年数计算出天数,第二个函数根据月和日计算出两个日期之间的天数(不理会中间的整年数)。

在深入的考虑这两个函数的具体实现算法时,会发现它们都需要判断一年是否是闰年,于是设计另一个函数IsLeapYear()完成此功能:

//根据年数判断其是否为闰年
static bool IsLeapYear(int year)
{
     //……
}

这样,函数CalculateDaysOfTwoYear()和CalculateDaysOfTwoMonth()在需要的时候即可调用IsLeapYear()函数来判断是否某年为闰年。

至此设计工作完成,得到以下结果:

CalculateDaysOfTwoDate

CalculateDaysOfTwoMonth         CalculateDaysOfTwoYear

IsLeapYear

以上展示了结构化分析得到的设计方案,箭头表示函数调用关系。

在整个结构化分析过程中,我们采用的是先设计出最顶层的CalculateDaysOfTwoDate()函数的接口,再设计第二层的两个函数CalculateDaysOfTwoMonth()和CalculateDaysOfTwoYear(),最后抽象出第三层的函数IsLeapYear()。

有了设计图,即可动手写代码。现在有四个函数需要开发,如何确定开发顺序?

很明显,必须先开发IsLeapYear()函数,因为此函数被其它函数调用,但它不调用其他的函数。

接着可以开发CalculateDaysOfTwoMonth()和CalculateDaysOfTwoYear()两个函数,因为CalculateDaysOfTwoYear()函数比较简单,所以先开发它。

最后开发CalculateDaysOfTwoDate()函数。

上述开发次序的确定可以用两句话来表达:

(1)盖楼先打地基:先开发最底层的函数,因为不完成开发这些函数,调用它们的上层函数就无法运行。

(2)柿子捡软的捏:在同一层次的函数中,先开发简单的,再开发复杂的。

函数开发完成之后,以下代码调用最顶层函数CalculateDaysOfTwoDate()完成计算两日期之间天数的工作:

MyDate d1, d2; //起始日期和结束日期

//1999年5月10日
d1.Year = 1999;
d1.Month = 5;
d1.Day = 10;
//2006年3月8日
d2.Year = 2006;
d2.Month = 3;
d2.Day = 8;
//计算结果

int days = CalculateDaysOfTwoDate(d1, d2);

现在可以对结构化编程方法做个小结。

① 结构化软件系统的基本编程单位是函数。

② 整个系统按功能划分为若干个模块,每个模块都由逻辑上或功能上相关的若干个函数构成,各模块在功能上相对独立。

③ 公用的函数存放在公用模块中,各模块间可以相互调用,拥有调用关系的模块形成一个树形结构,这种调用关系应尽可能做到是单向的。

结构化软件系统的架构:

主控模块

子模块     ↓     子模块

公用模块

结构化编程的开发过程可以分为以下三个阶段:

(1)分析阶段:在编程之前,需要仔细分析要解决的问题,确定好数据结构与算法。

(2)设计阶段:结构化编程的基本单元是函数,每个函数都完成整个程序的一个功能,整个设计过程就是函数接口的设计过程,这是一个“自顶向下,逐步求精”的过程,将一个大函数不断分解为多个小函数,直至可以很容易用某种程序设计语言实现时为止。

(3)编码阶段:在开发时,根据在设计阶段得到的函数调用图,先开发最底层的函数,再开发上层函数。这是一个“自底向上,逐层盖楼”的方法。

结构化编程中“自顶向下,逐步求精”的“功能分解法”,是一种重要的软件开发方法,其本质是一种“分而治之”的思维方式,在面向对象的程序中也有广泛的应用。掌握这两种分析方法,对软件工程师而言是非常重要的。

(2)面向对象分析过程 

有了结构化分析的基础,可以很容易的将原先结构化的程序转为面向对象的程序。

创建一个CalculateDate类,作为上面结构化分析得到的四个函数的“新家”,如图:

由于外界只需要调用CalculateDaysOfTwoDate()一个函数,所以将此函数设置为公有(public),而其它三个函数则成为类的私有(private)成员,外界不可访问。

以下为调用此类完成计算两个日期间天数的代码示例:

MyDate d1, d2;
//MyDate d1, d2; //起始日期和结束日期
//1999年5月10日
d1.Year = 1999;
d1.Month = 5;
d1.Day = 10;
//2006年3月8日
d2.Year = 2006;
d2.Month = 3;
d2.Day = 8;

string str = "{0}年{1}月{2}日到{3}年{4}月{5}日共有天数:";
str = String.Format(str, d1.Year, d1.Month, d1.Day, d2.Year, d2.Month, d2.Day);
CalculateDate obj = new CalculateDate();//创建类CalculateDate对象obj
//调用对象obj的CalculateDaysOfTwoDate方法计算
int days = obj.CalculateDaysOfTwoDate(d1, d2);
Console.WriteLine(str + days);

对比前面结构化的程序,不难发现面向对象的程序具有以下几个特点:

(1)所有的函数都放入到一个类中,成为某个类的成员,类是编程的基本单元。

(2)外界不能直接调用类的成员函数,必须先创建一个对象,再通过对象来调用这些函数。

(3)只有声明为public的函数可以被外界调用,其余声明为private的函数是私有的,外界无法访问。

从这个实例可以看出,面向对象程序与结构化程序相比没有明显的优越性,而且显得更麻烦,但如果是大规模的软件系统,则面向对象程序就有着结构化程序不可比拟的优势,简单地说:

对于大规模的系统,采用面向对象技术开发可以达到较高的开发效率与较低的维护成本,系统的可扩展性也更好。

其实.NET Framework本身就提供了两个类DateTime和TimeSpan可完成同样的功能:

对比一下,显然使用.NET Framework提供的现成类比我们手工编写代码完成同样的工作开发效率要高得多。.NET Framework中所提供的现成代码都是以面向对象的形式封装的。实践证明,当需要大规模的复用代码以提高软件生产率时,面向对象比结构化技术更有效。

时间: 2024-10-19 03:00:09

一、面向对象技术概论(上)的相关文章

面向对象技术概论

面向对象理论很早就被提出了,但它真正地渗透到软件开发的各个领域,并且在软件开发实践中大规模应用,却要等到上世纪九十年代.到目前为止,面向对象技术已是软件开发的主流,全面取代了结构化编程技术曾经具有的地位. 面向对象技术与结构化编程技术有着不同的风格,但同时也有着密切的联系.从具体编程角度来看,面向对象技术与结构化编程技术很难截然分开,两者的根本差别在于思维 方式. 要了解面向对象技术,得从结构化编程技术入手. 1.1结构化编程引例 结构化编程在上世纪七十年代兴起,由于它具有很多的优点,出现之后没

一、面向对象技术概论(下)

1.2 面向对象的核心概念 从理论上说,面向对象技术拥有四大基本特性. (1)封装 这是一种隐藏信息的特征.拿上节引例来说,类CalculateDate将数据结构与算法隐藏在类的内部,外界使用者无需知道具体技术实现细节即可使用此类.封装这一特性不仅大大提高了代码的易用性,而且还使得类的开发者可以方便的更换新的算法,这种变化不会影响使用类的外部代码.可以用以下公式展示类的封装特性: 封装的类=数据+对此数据所进行的操作(即算法) 通俗的说,封装就是:包起外界不必需要知道的东西,只向外界展露可供展示

面向对象技术

c#是面向对象的编程技术,所以要了解面向对象的知识十分重要.要编写出结构合理的c#代码语句,必须掌握面向对象编程技术的基本知识. 什么是OOP? 面向对象程序设计即OOP,是Object-OrientedProgramming的缩写.与函数式程序设计和逻辑是程序设计所代表的接近于机器的实际计算模型所不同的是,OPP几乎没有引入精确的数学描述,而是倾向于建立一个对象模型,它能够反映实体之间的联系. 对象的产生基于两种方式:原型,类. 面向对象技术具体分为面向对象分析(OOA)和面向对象设计(OOD

PHP面向对象技术(全面讲解)

PHP面向对象技术(全面讲解) 本部分一共包括以下一些技术点: 1.面象对象的概念 2.什么是类, 什么是对象, 类和对象这间的关系 3.什么是面向对象编程呢? 4.如何抽象出一个类? 5.如何实例化对象 6.如何去使用对象中的成员 7.特殊的引用"$this"的使用 8.构造方法与析构方法 9.封装性 10.__set() __get() __isset() __unset()四个方法的应用 11.类的继函 13.重载新的方法 14.访问类型 15.静态成员以及类中常量的使用 16.

你的面向对象技术在哪个级别?

你的面向对象技术在哪个级别? 怎样才算掌握OOP 1. 能把面向对象和具体语言的对象抽象联系起来 在面向对象刚刚入门的时候,一大顿理论加上解释又是只言片语,什么原则,方法等根本好像是没有用的嘛.唯一看明白的就是对象,类就是Class. 在编程的时候,碰到一个名词就把它写成class,以为这就是面向对象编程.拿图书馆案例来讲,初步分析后可能就把我们的学生Student作为我们的 Class来编程,并设计了它的属性,方法和操作,具体来说就是给Student加上了name属性,借书方法等. 仿佛面向对

好程序员前端学习路线分享模拟JavaScript中面向对象技术

好程序员前端学习路线分享模拟JavaScript中面向对象技术,在C#和Java语言中,面向对象是以类的方式实现的,特别是继承这个特性,类的方式继承表现出了强大的功能,而且也易于学习.JavaScript不是纯的面向对象的语言,而是基于对象的语言,对象的继承是以原型函数的形式继承的,很多初学者刚开始接触的时候不太理解,但是JavaScript这种以原型函数的形式实现面向对象技术,不仅是可行的,而且还为面向对象技术提供了动态继承的功能,本文主要讨论了JavaScript的面向对象技术.?一.原型对

OS X 和iOS 中的多线程技术(上)

OS X 和iOS 中的多线程技术(上) 本文梳理了OS X 和iOS 系统中提供的多线程技术.并且对这些技术的使用给出了一些实用的建议. 多线程的目的:通过并发执行提高 CPU 的使用效率,进而提供程序运行效率. 1.线程和进程 进程 什么是进程 进程是指在计算机系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行中其专用且受保护的内存空间内 比如同时打开 Xcode .Safari ,系统就会分别启动两个进程 通过活动监视器可以查看Mac系统中所开启的进程 线程 什么是线程 一

【菜鸟也疯狂UML系列】——面向对象技术

从软工开始,我们就开始接触面向对象了,接下来的学习资料好像都有提到面向对象,以后就要和她交朋友了,所以,我们就要对她了解多一点点. 一.何为面向对象? 面向对象(Object Oriented),是将现实世界映射成的一个个独立的对象,这些对象之间原本没有关系,只是加上一点魔术粉,她们就会相互传递消息,从而形成一个"过程".举个比较生动的例子:我韩梦甜,和刘文彬原本是两个八竿子打不着的人(一个南方,一个北方),可是在书法协会这个外力的作用下,我们相识相知相爱,传达爱意,从而形成了一个&q

面向对象技术的软件设计

面向对象技术(Object-Oriented Technology).面向对象技术强调在软件开发过程中面向客观世界或问题域中的事物,采用人类在认识客观世界的过程中普遍运用的思维方法,直观.自然地描述客观世界中的有关事物.面向对象技术的基本特征主要有抽象性.封装性.继承性和多态性. 对象模型化技术(OMT) 对象模型化技术把分析时收集的信息构造在三类模型中,即对象模型,功能模型和动态模型 对象模型:最关键的模型,描述系统的静态结构,包括构成系统的类和对象,以及他们之间的关系 在对象模型化技术中,类