跟“面向对象”说声:你好!——从零开始学习面向对象(一)

引言

      最近收到了一大学室友的邮件,问我学习ASP.NET该从何入手?回想起这哥们儿,大学四年基本就没出过寝室,成天就玩儿网游了,怎么说也考进了全国排名前十的学府,学习当时炙手可热的专业……现在突然想学ASP.NET了?嘿嘿,看来是想改过自新,从头开始了。想当年那哥们儿学业荒废了,我作为其室友也不无责任。这也成为我写这篇文章的初衷。

      本文面向刚接触并想学好面向对象编程的初学者,权当抛砖引玉之意,老鸟可以无视。

面向对象究竟好在哪里?     

      闲话就不多说了, ASP.NET是一个全面向对象的技术,不懂OO,那绝对是学不下去的! 什么?你不知道啥是OO? 好吧,OO英文全称Object Oriented,即面向对象编程方法。老是听别人说用OO怎么怎么好,用OO开发效率怎么怎么高,那我们究竟为什么要面向对象呢?先别急,我们先来了解下之前的面向过程。

      面向过程编程,即结构化编程,基本方法是“功能分解法”,就是将要解决的实际问题进行分解,把一个大问题分解成若干子问题,每个子问题又可以分解为更小的问题,直到得到的子问题可以用一个函数来实现为止。也就是说,结构化编程的基本单位是函数。还记得学习C语言的时候老师是如何讲解结构化编程的原则的么?功能过程化,过程最小化。功能过程化即用一个过程或者函数来实现一个功能,供其它地方要使用此功能的地方调用,从而达到重用的目的。过程最小化即把一个大过程分解成好多个小过程,这样能够保证代码的可维护性和阅读性。

      现在我们从一个简单的例子开始,逐步体会面向过程编程和面向对象编程的不同。请看经典C语言程序100例中的一个简单例子:

      输入某年某月某日,判断这一天是这一年的第几天?

      这是一道简单的算术问题。基本思路是这样的:将这一天所在月份之前的每一个月天数累加,然后看这一天是几号便再加几天。存在闰年的特殊情况,如果这一天在闰年中且月份大于2时需要多加一天。

      根据以上思路,计算步骤如下:

      步骤1 计算该日所在月之前所有月份天数总和,并加上该日对应的当月天数;

      步骤2 判断该月是否大于2月,如果大于2月,则判断该年是否是闰年,如果是闰年则再加上1天。

      根据以上步骤,按照结构化编程方式我们可以用一个函数CalculaeDays()来实现。程序如下:

 

// 日期结构
public struct InputDate
{    
    
public int Year;
    
public int Month;
    
public int Day;
}

//计算输入日期之前天数
static int CalculateDays(InputDate myDate)
{
    
//……
}

      接着,我们把CalculateDays这个过程分解,写出以下几个函数:

//判断是否是闰年且是否大于2月,如果都成立则返回true
static bool IsLeapYear(InputDate myDate)
{
    
//……
}

//计算输入日期所在月份之前的所有月份天数之和,并加上该日对应当月天数
static int CalculateDaysBeforeMonth(InputDate myDate)
{
    
//……
}

//调用IsLeapYear()函数判断返回值如果为true则将天数再加1
static int CalculateDaysOfLeapYear(InputDate myDate)
{
    
//……
}

      这样,我们在CalculateDays()函数中调用这些函数则可以得到最终的结果。

InputDate date1;
//2008年8月8日
date1.Year = 2008;
date1.Month 
= 8;
date1.Day 
= 8;
//调用CalculateDays方法计算结果
int number = CalculateDays(date1);

      可以看到,面向过程式的编程方法以函数这个基本单位,将整个过程分解为一个个的子过程,而子过程或者说是模块之间又可以相互调用,最终完成整个功能。以前在网上看到,说面向过程其实可以描述为谓语+宾语,即怎么做、做什么,十分形象。

      现在我们再以面向对象的方法来考虑以上问题。

      我们首先设计一个Calculate类,里面包含了以上分析得到的四个函数:

//Calculate类
public class Calculate
{
    
//计算输入日期之前天数
    public int CalculateDays(InputDate myDate)
    {
        
//……  
    }
    
//计算输入日期所在月份之前的所有月份天数之和,并加上该日对应当月天数
    private int CalculateDaysBeforeMonth(InputDate myDate)
    {
        
//……
     }
    
//调用IsLeapYear()函数判断返回值如果为true则将天数再加1
    private int CalculateDaysOfLeapYear(InputDate myDate)
    {
        
//……
     }
    
//判断是否是闰年且是否大于2月,如果都成立则返回true
    private bool IsLeapYear(InputDate myDate)
    {
        
//……
     }
}

      接着,我们可以这样来用:

InputDate date1;
//2008年8月8日
date1.Year = 2008;
date1.Month 
= 8;
date1.Date 
= 8;
//创建Calculate类的对象cal
Calculate cal = new Calculate();
//调用Calculate类的公用方法CalculateDays()计算
int number = cal.CalculateDays(date1);

      可以看到,面向对象编程以类为基本单元,外界通过创建类的对象来调用其成员函数,且只有声明为public的函数才能被外界调用,private函数外界无法访问。有人说面向对象可以描述为主语+谓语,即谁来做、怎么做,也是十分形象和贴切。

      说到这里,你可能会说,似乎没有看到面向对象比面向过程有明显的优越性啊,其实优势是显而易见的:

      我们知道,在软件开发过程中,开发效率直接影响开发成本,开发出的系统可扩展性影响着系统的性能和维护,我们可以通过面向对象方法中的各种机制重用我们已经写好的类,而不象结构化编程中功能单一的函数。同时,如果需求变更,我们也只需要修改类中实现该功能的相关的代码,而不需要象在面向过程编程中大篇幅的修改,最终可维护性和扩展性都差。当然,我只是列举了简单的几点,面向对象编程方式还有很多优点,随着我们学习的逐渐深入,就会逐渐领会和理解。

结束语

      这一篇中介绍了面向过程与面向对象的区别,同时介绍了面向对象编程的优越性。在下一篇中,将介绍面向对象的四大基本特性:封装,抽象,继承和多态。

posted @ 2008-07-28 17:27  lovesummer  阅读(455)  评论(2)    收藏  举报