面向对象----抽象的应用

原创 2013年12月03日 21:55:10

    抽象与分解是面向对象编程中的基本方法。人类理解问题的方式通常是抽象出一类问题的定义,然后根据这个定义来认识问题。通常抽象可分3类:

             1. 抽象名词定义: 

                        就是大家已经对一些社会或自然界已经存在的事物已经有了抽象的定义了。比如森林,森林是个抽象的定义,表示有很多不同树木和其他植物组成的地方。如果我们程序里要表示森林,可以这样: 

             class Tree{}; class Grass{};

           class  ATree:public Tree{}: class BTree:public Tree{};

               class Forest{

.......................

                                        vector<Tree*>  m_cTrees; 

                                       vector<Grass*> m_cGrasses;

};                     

            2.抽象行为定义

                             就是对某种特定的行为进行概括定义。比如羊吃草,狼吃羊,都可以概括为动物进食,我们可以在程序里这样表示:

            class Animal{

                           virtual       void   feed()=0;

} ;

           class Sheep: Animal {


                      void  feed()

{

         printf("eat grass"); 

}

   class Wolf: public Animal {

          void feed(){
               printf     ("eat sheep");

}

};

         3. 自定义抽象

              除开1,2外的抽象都可以归结为此类。  软件中不是所有的概念和行为大家都有确定的定义。比如我们要统一处理森林里的所以动物,那么为了方便处理,我们通常可以定义一个vector<Animal*> 对象,

   但是为了方便理解和处理,我们可以将其抽象为动物管理器: 

  class     AnimalMgr  {

                 vector<Animal*> m_cAnimals;

        public:

                 int GetMaxAnimal() ; // 找到数量最多的动物,返回其在数组中的位置

                void PushNewAnimal(Animal* pAn); //增加新的种类

 };


   我们通过一个简单的文件读取工作来实际了解下抽象的运用:

       比如1.  从一个文件中读取出字符,并打印出来,但只需要处理字符等于 'a'  或 'c'的字符。这个问题很简单,基本用不到抽象:

         void workForFile(char* filename)

          {

                         f = fopen(fiename);

                        while(c =  readchar(f))

                         {

                             if( c =='a' || c=='c')
                                printf(c);

                      }

}

 2. 客户对需求有了变化,要求字符等于 'a'  或 'c'或等于"bd"或“db" 于是,我们修改如下: 


void workForFile(char* filename)

{

         f=fopen(filename); 

       

        string s ;

        while(c=readchar(f))

       {

            s+=c;

           if(*s.data() = 'a' ||*s.data()=='c' ||  strcmp(s.data(),"bd") ==0|| strcmp(s.dat(),"db")==0)

              printf(c);

          }

}

看起来这里对字符串的过滤是个容易变化的东西,并且还有一点复杂, 我们修改如下:

 

bool Filt(string s)

{

      if(*s.data() = 'a' ||*s.data()=='c' ||  strcmp(s.data(),"bd") ==0|| strcmp(s.dat(),"db")==0)

         return true; 

       return false;

 }

void workForFile(char* filename)

{

         f=fopen(filename); 

       

        string s ;

        while(c=readchar(f))

       {

            s+=c;

           if(Filt(s))

              printf(c);

          }

}

我们把过滤行为抽象为Filt 函数 ,这样我们的workForFile 就被抽象为打开文件,读取字符,过滤字符,与打印字符 4个行为,而与具体的a,c,bd 过滤方式无关,

这样 workForFile函数看起来更简单,容易理解。更重要的是,workforfile  函数经过抽象后, 更稳定了,与变化无关了(过滤字符的变化只需要修改filt)。这个就是OO原则:依赖抽象不依赖具体的

一个很好的理由。因为抽象更稳定。

 

3. 当客户需要动态改变过滤方式的时候, 比如A 文件 需要过滤 'a',B文件则只需要过滤'b',  这种情况我们提供的filt函数好像不够用了, 我们需要多提供

一个函数:

typdef   void (*pfnFilt) (string s) ;


  void FiltA(string s)

{
...

};

 void FiltB(string s)

{

......

}

      void workForFile(char* filename,pfnFilt )

      {

         f=fopen(filename); 

       

        string s ;

        while(c=readchar(f))

       {

            s+=c;

           if(pfnFilt(s))

              printf(c);

          }

    } 


int main()

 {

        workForFile("a",FiltA);

         workForFile("b",FiltB);

 return 0;

  } 


这里我们将Filt A,FiltB 抽象为 一个提供过滤功能的函数指针,如果我们将其用类来表示:

 class Filter {

public:

           virtual  bool Filt(string s)=0;

};


class FilterA:public Filter

{public:

          bool Filter(string s)

{

         return  FiltA();
}

 };

class FilterB:public Filter

{public:

        bool  Filt(string s)

 {

        return FiltB(s);

}

    }

          

 void workForFile(char* filename,Filter* pFilter)

      {

         f=fopen(filename); 

       

        string s ;

        while(c=readchar(f))

       {

            s+=c;

           if(pFilter->Filt(s))

              printf(c);

          }

    } 


4. 如果客户不想仅仅只是处理文件,还要求可以处理网络上传入的数据.则我们将文件与网络数据处理抽象为IO处理类:

class IoProcess{

protected:

          HANDHLE hIo; 

Filter * m_pFilter;

 public:

      virtual char ReadChar() =0 ;读取行为被抽象出来了, 因为可能读的方式有所不同


            virtual void Work () // 看上去,这个很稳定,没有什么需要修改的,所以可以放到这里

            {

        string s ;

        while(c=ReadChar(m_hIo))

       {

            s+=c;

           if(pFilter->Filt(s))

              printf(c);

          }


               }

}


class FileProcess:public IoProcess{

          FileProcess(char* pfile,Filter* pFilter){

  hIo = fopen(pfile): 

             m_pFilter  = pFilter;

};

          char ReadChar()

{

  .....

}

}; 


class   NetProcess:public IoProcess{


              NetProcess(socket s,Filter * pFilter)

            {


        hIo = s;

 m_pFilter = pFilter;


 }  


      char ReadFile()

  {...

  }

  };


int main()

{

        IoProcess  * p = new FileProcess( "a", new FilterA());

        IoPorcess* pp = new NetProcess(sock ,new FilterB());


  }

 这里看上去与设计模式的 BRIDGE 有很像,嘿嘿 ,所以设计模式也是抽象的某种特例吧。

                      

              

谈谈面向对象 之 抽象

一、引言 在上一篇博客中,我们谈了面向对象的基本概念,从这篇开始,我们谈谈面向对象的几个特征:抽象、封装、继承、多态。我们首先要谈的特征是抽象。 不止一位同事将抽象这一特征排除在外,认为面向对象有三个...
  • hxtan
  • hxtan
  • 2013年12月09日 08:45
  • 3497

抽象的概念,对象的概念,面向对象和面向过程的区别

1.什么是抽象 抽象就是把一个对象的分析出各个属性,来代替表达的手法 抽就是分离,象就是表示出来的部分 比如说把一个学生对象抽象一下,就剩下他的一些属性和行为,例如姓名,性别,年龄,身高,学习的...
  • maixinyue
  • maixinyue
  • 2016年10月20日 23:03
  • 1004

深入Java系列——面向对象之(一)——抽象

此次对于java的学习,可谓是很轻松的一个过渡。在软考过程中不知不觉就和她成为好盆友了。从之前的VB、C#、 C++基础学习,到现在的java,一个感受就是编程语言大概都是一样的,无非都是指挥机器按照...
  • u011500356
  • u011500356
  • 2015年11月18日 16:30
  • 1358

面向对象编程之抽象

面向对象编程 公司投资没有了,人们陆续都离职了,正好可以抽出个时间看看书,C++ Primer第四版,以前粗略的读过一遍,但是一直感觉好多地方就那么过去了,读书这个事情就是这样,每读一遍,都能有许多新...
  • WM_jiangnanan
  • WM_jiangnanan
  • 2015年01月19日 15:18
  • 1028

c++ 面向对象高效编程 【笔记】什么是数据抽象?

数据抽象
  • sinat_26908721
  • sinat_26908721
  • 2016年11月07日 18:57
  • 404

java面向对象的四大特性-多态,继承,抽象,封装

1.多态 面向对象的四大特性:封装、继承、多态、抽象。从一定角度来看,封装和继承几乎都是为多态而准备的。是最重要的知识点。多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对...
  • basycia
  • basycia
  • 2016年07月07日 12:54
  • 4024

浅谈PHP面向对象的几个抽象概念

本人专攻PHP+大数据集群,利用课余时间想巩固一下底层的C++和LINUX课程。写博客,一方面可以以博客的方式记录自己的程序猿之路,另一方面也可以起到前人种树后人乘凉的作用。计算机中这些概念有的时候很...
  • php_wyl
  • php_wyl
  • 2016年10月22日 01:02
  • 529

面向对象的编程语言有封装、继承 、抽象、多态等4个主要的特征

计算机软件系统是现实生活中的业务在计算机中的映射,而现实生活中的业务其实就是一个个对象 协作的过程。面向对象编程就是按现实业务一样的方式将程序代码按一个个对象进行组织和编写,让计算机系统能够识别和理解...
  • chenpengchenggong
  • chenpengchenggong
  • 2014年07月21日 21:17
  • 1238

黑马程序员-Java中面向抽象和面向接口设计

黑马程序员-Java中面向抽象和面向接口设计 在讨论面向抽象和面向接口之前,先来粗略了解下“开闭原则”。 最近在搜索问题的时候总是会看到有人提到“开闭原则”的设计思想。今天就稍微总结下JavaS...
  • Most_want
  • Most_want
  • 2015年10月07日 14:45
  • 513

C++之面向对象程序设计的基本特点(抽象、封装、继承、多态)

编写程序的目的就是描述和解决现实世界中的问题。第一步就是将现实世界中的对象和类如实的反映在程序中。 面向对象程序设计的主要特点:抽象、封装、继承、多态。 1、抽象 定义:对具体问题(对象)进行概括,抽...
  • Mary19920410
  • Mary19920410
  • 2017年04月09日 22:05
  • 662
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:面向对象----抽象的应用
举报原因:
原因补充:

(最多只允许输入30个字)