网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.用.NET的System.Globalization来.
.休闲程序空间:趣说java处理异常的.
.用JAVA访问共享文件系统.
.为什么Java中继承是有害的二.
.EJB最佳实践:构建更好的异常处理.
.CLR和JRE的运行机制的初步总结.
.Java项目中使用Hibernate处理数据.
.Java Mail API及其应用 —— 一个.
.Class文件详解 (1).
.Web 服务代理组件创建 JSF Web 服.
.在Java EE环境下使用Kodo EJB.
.类的转换.
.怎样在APPLET中发EMAIL javamail.
.轻松从VB转向基于Swing的开发平台.
.Rational Rose介绍材料.
.Web App struts框架里实现Filter.
.Java如何调用可执行文件和批处理.
.使用Java操作文本文件.
.关于Java的点滴看法.
.WebSphere Enterprise Scheduler.

多态与面向对象(一)

发表日期:2008-1-5



  不管时光如何流逝,应该说每个人对他职业生涯的第一次面试都是记忆犹新。不是吗?
  
  经过前两轮的筛选,我推开那扇门,小心翼翼地坐在Andy面前。我应聘的职位是C++程序员。坦率的讲,我有一些紧张。您知道的,一个找不到工作的应届大学生,生活是如何地布满压力。
  
  “能告诉我什么是OO吗?”Andy一开口就是这样一句。
  
  我有预感,他将主要考察我在面向对象方面的编程能力。我知道C++支持数种不同的程序设计风格,包括面向过程的编程风格(Procedural Programming)、泛型编程风格(Generic Programming)、基于对象的编程风格(Object-base Programming)和面向对象的编程风格(Object-oriented Programming)。可是什么是OO呢?具体概念,我还真的不大清楚。
  
  “分析问题时,我们经常会把事物看作一个一个的对象,把具有相同特征的对象看作一个类......”我想他是不是在期待这样的答案呢。
  
  “那你对OB又作何解释呢?”Andy面无表情。
  
  对呀,所谓OB,就是被称作ADT(Abstract Data Template)的程序设计风格,我刚刚所说的不也被OB所支持吗?一直以为自己在使用面向对象编程技术,谁知道......哎,真是惭愧啊。
  
  “是的,应该说OO留给我印象最深的还是继续和多态。”现在我只能尽量回想我曾参与过的少得可怜的项目以寻求答案。
  
  “几乎每个人都同意继续和多态是OO概念,可是据我所知,真正理解这两个概念的却不多。时间有限,我们就谈谈多态。你知道C++以哪些方法支持多态吗?”显然他不想在我身上花太多时间。
  
  这个问题对于我还是不难回答的。例如有以下继续体系:
  
  其中rotate是一个虚拟函数,C++ 以三种方法支持多态。其一,经由一组隐含的转化操作,如把一个派生类指针转化为一个指向其公有基类类型的指针:
  
  shape *ps = new circle();
  
  其二,经由虚拟机制,如
  
  ps->rotate();
  
  其三,经由dynamic_cast和typeid运算符。如
  
  if (circle *pc = dynamic_cast(ps)) ......
  
  “多态的主要用途是经由一个共同的接口来影响类型的封装,这个接口通常被定义在一个抽象的base class中。这个接口是以virtual function机制引发的,它可以在执行期根据object的真正类型解析处到底是哪一个函数实体被调用。”趁热打铁,我敢肯定假如还不能趁此机多说几句的话,那将是前功尽弃。
  
  “假如我写下这样的代码又将怎样呢?”Andy飞快地在一张纸片上写下:
  
  circle p;
  
       shape s(p);
  
       s.rotate();
  
  以一派生类对象为初值初始化一个基类对象!这是我的第一反应。
  
  “这会发生所谓的对象切割,同时多态不再呈现。”虽然我敢肯定我所说的话语,可我总感觉Andy另有它意。
  
  “为什么多态不再呈现?”他的眼神流露出一丝疑问。
  
  “因为多态的特性只有在使用pointer或reference时才能发挥。”我毫不犹豫的回答。
  
  “好吧,请你讲讲曾参与过的设计。”Andy似乎已经达到目的。后来我才知道,C++通过class的pointer和reference来支持多态,这种程序设计风格就是所谓的OO。
  
  我想起曾经参与的一个项目,我的主要任务是通过串口来控制一种叫做云台的外设,其实就是根据通信协议将客户请求翻译成相应的字符串,然后通过串口发送出去。看起来很简单,是吗?不过,为了争取更大的市场,我们必须尽可能多的支持不同厂商提供的不同协议,并且能够在未来方便地加入当前尚未支持的协议。当时的设计就似乎这样子:
  
  class CPtzHal
  
  {
  
  public:
  
       CPtzHal(CSerial *pSerial, CProtocol *pProtocol);
  
       void sendCommand(int command);
  
  private:
  
       CSerial    *m_pSerial;
  
       CProtocol *m_pProtocol;
  
  };
  
  成员函数sendCommand的定义如下:
  
  void CPtzHal::sendCommand(int command)
  
  {
  
       if(m_pSerial != NULL && m_pProtocol != NULL)
  
       {
  
            m_pSerial->send(m_pProtocol->getCommandString(command));
  
       }
  
  }
  
  您看,我们使用CPtzHal 来接受并处理用户的请求。CProtocol 就是我们的协议类,通过其成员函数getCommandString 得到指定的请求ID所对应的应该发往串口的字串;CSerial实际上是串口类,而CSerial::send的作用当然是把指定的字串发送出去。
  
  “那么,你是怎么保证方便的添加新协议呢?”Andy轻轻移了移身体。
  
  “如您所知,CProtocol理所当然是一个基类,而且我把它设计成一个抽象基类,所有的具体的协议类都将从它派生。”我缓缓说道,同时写下以下代码:
  
  class CProtocol
  
  {
  
  public:
  
       virtual ~CProtocol(){};
  
       virtual string getCommandString(int) = 0;
  
  };
  
  “您看,因为是一个基类,其析构函数当然要声明为virtual……”
  
  “等等,既然析构函数什么都不做,为什么要给它一个空的函数体?”Andy开始试探我。
  
  “正如我刚才所说,我是有义务要声明它们的。本来我也不想给出实现,可是即使我同意,编译器也不会答应啊。”
  
  “嗯,不错。”Andy的首肯令我颇有些难为情。
  
  “至于每一个具体的协议类,都必须实现在CProtocol中声明的那些纯虚函数(pure virtual function)。”我飞快地写出以下代码:
  
  class CIntelProtocol : public CProtocol
  
  {
  
  public:
  
       string getCommandString(int command);
  
  };
  
  
  
  string CIntelProtocol::getCommandString(int command)
  
  {
  
       // 返回相应的字串
  
  }
  
  “您看,CIntelProtocol正是封装了英特尔的协议。当有新的协议加进来的时候,做法就如同以上一般,从CProtocol派生出一个新的协议类。”
  
  从Andy的表情可以看出,他还算满足。作为协议类的客户,CPtzHal并不需要知道这个具体协议到底是英特尔的还是三星的,说不准它是将来某个别的厂商所提供的。可是这有什么关系呢?不管这点如何改变,CPtzHal压根就不用变。这,正是多态所带来的好处。
  
  我和Andy的对话就这样结束了吗?不,还没有。这正如我要跟你讲的有关OOP的故事,还将继续。
上一篇:基于.Net的AOP实现技术 人气:698
下一篇:使用.net Remtoing并行计算 人气:608
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐