以下代码,想用多态方式来替换if else,网上说的最多的是 if 判断的时候是判断类(class)的类型
而非整形或者数字类型。
如果 if 判断的是类类型,确实容易用多态实现。
下面的例子是整型值判断。我想求教下各位,这样能不能用多态的方式实现,或者给写建议,谢谢各位了
procedure TForm1.proc1();
begin
  ShowMessage('proc1');
end;procedure TForm1.proc2();
begin
  ShowMessage('proc2');
end;procedure TForm1.proc3();
begin
  ShowMessage('proc3');
end;procedure TForm1.ExtractedMethod1;
begin
  if ComboBox1.ItemIndex = 0 then
  begin
    proc1;
  end
  else if ComboBox1.ItemIndex = 1 then
  begin
    proc2;
  end
  else if ComboBox1.ItemIndex = 2 then
  begin
    proc3;
  end;
end;

解决方案 »

  1.   

    从这个例子看,“多态”需求不是必须,改成case足矣
      

  2.   

    写成多态,个人觉得更绕圈子,直接一个CASE语句就可以搞定的
      

  3.   

    而且可以写成 procs(index: integer);  // procs(ComboBox1.ItemIndex);
      

  4.   

    我感觉也是写成case语句判断就可以了。
    procedure proc(index:integer);
    Begin
      case index of
        0:;
        1:;
      end;
    end;
    判断index值就可以了。如果感觉index不直观,可以声明成枚举类型。
      

  5.   

    谢谢楼上各位回复我这个只是举个例子实际我的程序里proc函数里做的事情还是挺多的,不仅仅是做个showmessage0 可以看成是串口方式控制
    1 可以看成网络控制
    2 可以看成USB控制这些控制的实现都是比较复杂的,另外程序的很多地方都用到了类似的判断。所有我想做些重构,先从if判断开始。可能我是为了重构而重构,不过程序的代码有比较多的地方有用到同一判断,只是这些判断是作为其他函数的一部分。
      

  6.   

    如果想用的话,写个简单例子好了。type 
      TCustomExternalController = class(TObject)
      protected
        procedure Step1; virtual; abstract;  
        procedure Step2; virtual; abstract;
        .... //自己按需要加方法,这里只是随便给个例子
      public
        procedure Execute;
      end;  TNetController = class(TCustomExternalController)
      protected
        procedure Step1; override;
        procedure Step2; override;
      end;  TUSBController = class(TCustomExternalController)
      protected
        procedure Step1; override;
        procedure Step2; override;
      end;  TSerialPortController = class(TCustomExternalController)
      protected
        procedure Step1; override;
        procedure Step2; override;
      end;implementationprocedure TCustomExternalController.Execute;
    begin
      //如果这些东西执行的过程类似,可以把执行过程抽象到这个方法里,子类覆盖具体步骤即可
      //关键字:模板模式。可参考TStream的实现方式。
      Step1;
      Step2;
    end;
    var
      AList: TObjectList;
      i: integer;
    begin
      AList := TObjectList.Create;   //关闭窗体时自己释放掉这个LIST
      AList.Add(TSerialPortController.Create);  
      AList.Add(TUSBController.Create);  
      AList.Add(TNetController.Create);  
      for i := 0 to ComboBox.Count - 1 do
        ComboBox.Items.Objects[i] := AList[i];
    end;
    procedure ComboBox.OnSelect(Sender: TObject);
    begin
      (ComboBox.Items.Objects[ComboBox.ItemIndex] as TCustomExternalController).Execute;
    end;
      

  7.   

    禁用UBB   内容存入剪贴板
      

  8.   

    嗯,Harryfin写的不错!
    一般思路就是这样!
    1.
    先写一个抽象类,来抽取子类的公用功能、公用函数以及公有成员(做成抽象类就是为了使终端程序员不要实现这个类,实现也没什么意义)
    2.子类继承抽象类
    3.应用反射机制,直接用Combobox中的名字生成对象
      

  9.   

    http://blog.csdn.net/liangpei2008/archive/2009/05/20/4204743.aspx
      

  10.   

    谢谢
    Harryfin
    我一会儿去单位看下。
      

  11.   

    看了你的帖子,相当好,非常感谢,想不到还有findclass这样的函数类似于java的反射机制
      

  12.   

    再学习下TypInfo里面的东西吧,你会知道更多
      

  13.   

    不用多态也可以,以前C没有类时就有这种需求,delphi可以这样写:
      p:array  [1..3] of  TProcedure; //定义指向过程的指针数组
    ...
    初始化数组:
    p[1]:= @TForm1.proc1;
    p[2]:= @TForm1.proc2;
    p[3]:= @TForm1.proc3;
    ...
    调用:
      p[ComboBox1.ItemIndex+1];
      

  14.   

    Harryfin:
       1.非常感谢,你的设计和精妙,说实话我是似曾看过,好像是第三方控件里看到过类似的写法。
       2.TypeInfo真的需要好好学习了,谢谢你的建议
      

  15.   

    keiy:
    感谢你的面向过程的设计来解决问题,不过我还是希望多态的方式来实现,目的是为了学习。
    楼上Harryfin和liangpei2008的回答已经可以解决我的问题,非常感谢!
      

  16.   

    如果你有exe + bpl開發程序,就比較常見了...
      

  17.   

    基本没用过exe + bpl方式开发程序。先谢了,有机会学习下