有时真的想问大家一句,delphi作为一个OOP有编程语言,那么这个OOP倒底要如何理解呢?您是如何理解这个OOP的那?还是一个铵钮点击之,再写上它的事件吗?还是我们来回的调用公用的函数或过程或是所写便所见呢?
您是如何想的呢?

解决方案 »

  1.   

    我觉得它是把所有的控件都定义为class,每添加一个控件就创建一个class的实例,并把它们封装到所在的窗体类中。至于属性和方法事件都是class的数据类型,是域(D5DG上的翻译)。
    我觉得这和传统的C++OOP的理念不大一样,感觉不是那么纯的oop,有种怪怪的感觉,不知大家有没有这个感觉。
      

  2.   

    楼上之所以有这种感觉,是因为用"搭积木"式的方式做程序做得太久了,以至于只看到了Delphi作为RAD工具的特性,而忽略了Object Pascal作为OOP语言的特性.
    C++Builder是使用C++语言,但它和Delphi差别很大吗?OOP语言只是提供给你一种工具,使用OOP语言编出的程序不一定是OO的.
      

  3.   

    我觉得,一个习惯于面向对象思想的程序员应该有一种"多分支过敏症",每当看到一个复杂的多分支语句时,首先应该想:我是不是可以用多态来作这件事?
    我曾经在一篇文章(讲C++的)中看到这样一句话:
    ,"那些可怜的C语言门徒才会使用switch语句处理不同的对象类型:
      
      /* A not-atypical C program */
      void f(struct someStruct *s)
      {
      switch(s->type) {
      case APPLE:
      /* do one thing */
      break;
      case ORANGE:
      /* do another thing */
      break;
      /* ... etc. ... */
      }
      }
      
      这些人学习Stroustrup教主的C++语言时,最重要的事情就是学习如何设计好的类层次。" 
    我觉得非常有道理.
      

  4.   

    楼上说:"那些可怜的C语言门徒才会使用switch语句处理不同的对象类型"未免太绝对了吧:
    比如我有一个图形类,它有几个子类:矩形,圆形,多边形,椭圆等,它的子类设计好后不会再变化,也不会再增加,现在我要对它们进行处理,如放大,变形等,不同的子类的同一种处理的代码是不一样的,如果不用多分支去判断,那该怎么作?
    不要告诉我说在父类中加一个放大的虚函数,这样的话,每次我增加一种处理操作就要把所有的类修改一遍.
      

  5.   

    我明白你的意思了。
    你说的问题是实体类的类层次稳定不变,但对它的处理经常扩充,何必要用多分支呢?一个Visitor模式轻松搞定:
    class TGraphVisitor;
    class TGraph
    {
    public:
      virtual void Accept(TGraphVisitor*)=0;
    };
    class TRectangle:public TGraph
    {
    public:
      virtual void Accept(TGraphVisitor* AVisitor);
    };
    void TRectangle::Accept(TGraphVisitor* AVisitor)
    {
      AVisitor -> Visit(*this);
    }
    class TCircle:public TGraph
    {
    public:
      virtual void Accept(TGraphVisitor* AVisitor);
    };
    void TRectangle::Accept(TGraphVisitor* AVisitor)
    {
      AVisitor -> Visit(*this);
    }
    //限于篇幅,假设TGraph只有两个衍生类。
    class TGraphVisitor
    {
    public:
      virtual void Visit(TRectangle& ARectangle)=0;
      virtual void Visit(TCircle& ACircle)=0;
    };
      

  6.   

    增加处理时只要增加一个TGraphVisitor的衍生类:
    TOutputName:public TGraphVisitor
    {
      public:
      void Visit(TRectangle& ARectangle);
      void Visit(TCircle& ACircle);
    };
    void TOutputName::Visit(TRectangle& ARectangle)
    {
    //这里对TRectangle类型处理。
    cout << "Rectangle\n";
    }
    void TOutputName::Visit(TCircle& ACircle)
    {
    //这里对TCircle类型处理
    cout <<"Circle\n";
    }
    main()
    {
      TGraph *ACircle = new TCircle, *ARect=new TRectangle;
      TGraphVisitor *Visitor= new TOutputName;
      ACircle->Accept(Visitor);
      ARect -> Accept(Visitor);
      delete Visitor;
      delete ACircle;
      delete ARect;
    }
    运行一下你就明白了。
      

  7.   

    TO  plainsong(伤心的风) 
    说的真好:)
      

  8.   

    不错!我也主张private的变量
    否则你要注意变量名的重复声明问题
    如unit1中public中声明str:string;
      unit2中public中又声明str:string;
      在unit3中同时引用了unit1,unit2,这时又要用全局变量str
    哈哈麻烦了
      

  9.   

    不是绝对的,
    OOP就一定是编程解决问题的最好方法?不是的,
    还有很多人在用纯C写大型应用程序呢,
    所以,请重视解决之道,只要能最好地解决问题,就是高效,
    而不管其是否时髦!
      

  10.   

    对不起,用C++讨论设计模式习惯了。我把上面的代码翻译了一下:
    type TGraphVisitor = class;
     TGraph = class 
     public
      procedure Accept(AVisitor: TGraphVisitor);virtual;abstract;
     end;
     TRectangle= class(TGraph)
     public
      procedure Accept(AVisitor:TGraphVisitor);override;
     end;
     TCircle=class(TGraph)
     public
      procedure Accept(AVisitor:TGraphVisitor);override;
     end;
    //限于篇幅,假设TGraph只有两个衍生类。
     TGraphVisitor= class
     public
      procedure Visit(ARectangle:TRectangle);overload;virtual;abstract;
      procedure Visit(ACircle:TCircle);overload;virtual;abstract;
     end;procedure TRectangle.Accept(AVisitor:TGraphVisitor);
    begin
      AVisitor.Visit(self);
    end;
    procedure TCircle.Accept(AVisitor:TGraphVisitor);
    begin
      AVisitor.Visit(self);
    end ;type
      TOutputName=class(TGraphVisitor)
      public
      procedure Visit(ARectangle:TRectangle);override;
      procedure Visit(ACircle:TCircle);override;
    end;
    procedure TOutputName.Visit(ARectangle:TRectangle);
    begin
    //这里对TRectangle类型处理。
    WriteLn('Rectangle');
    end;
    procedure TOutputName.Visit(ACircle:TCircle);
    begin
    //这里对TCircle类型处理
    WriteLn('Circle');
    end;
    var
      ACircle,ARect:TGraph;
      Visitor:TGraphVisitor;
    begin
      ACircle := TCircle.Create;
      ARect := TRectangle.Create;
      Visitor := TOutputName.Create;
      ACircle.Accept(Visitor);
    0A  ARect.Accept(Visitor);
      Visitor.Free;
      ACircle.Free;
      ARect.Free;
    end.
         ____     ____
         \ p \   / g /
          \ l \_/ n /
           \ a   o /
            \ i s /
             \ n /
              \_/
      

  11.   

    同意LuZhou的观点,世界上没有一种最好的解决问题的方法,要具体问题具体分析。
    面向对象的方法的优点是代码的可重用能力强,但工作量大,适用于将长期维护、升级的系统的开发。如果是一次性的制品就没必要用面向对象的方法了。
    不过,用C编程不一定就不是面向对象的,面积对象是一种方法,而不是工具,可以用很多开发工具实现(不过好象很难用VB实现)。     ____     ____
         \ p \   / g /
          \ l \_/ n /
           \ a   o /
            \ i s /
             \ n /
              \_/