Delphi 泛型 接口约束的实例 转

通过接受一个限定的参数,这个参数是实现某个接口的类,比较起直接接受泛型,而限制这个泛型的类要更加灵活。也就是通常所说的面向接口式的编程。这样可以 达到调用实现了这个接口的各种泛型的实例。这种对泛型使用接口约束的应用,在.net框架中有很广泛的应用。下面是一个实例(命名为 IntfConstraint)。

 

            首先,需要声明一个接口:

[delphi] view plaincopy

  1. type  
  2.   IGetValue interface  
  3.     ['{60700EC4-2CDA-4CD1-A1A2-07973D9D2444}']  
  4.     function GetValue: Integer;  
  5.     procedure SetValue (Value: Integer);  
  6.     property Value: Integer  
  7.       read GetValue write SetValue;  
  8.   end;  

 

         接下来我们定义一个类实现这个接口:

[delphi] view plaincopy

  1. TGetValue class (TSingletonImplementationIGetValue)  
  2.   private  
  3.     fValue: Integer;  
  4.   public  
  5.     constructor Create (Value: Integer); // 0);  
  6.     function GetValue: Integer;  
  7.     procedure SetValue (Value: Integer);  
  8.   end;  

 

        精彩内容从下面开始,接着我们定义一个泛型类,这泛型类被限定了是实现了(我们上面定义的)指定的接口:

[delphi] view plaincopy

  1. TInftClass  class  
  2. private  
  3.   val1, val2: T; // or IGetValue  
  4. public  
  5.   procedure Set1 (val: T);  
  6.   procedure Set2 (val: T);  
  7.   function GetMin: Integer;  
  8.   function GetAverage: Integer;  
  9.   procedure IncreaseByTen;  
  10. end;  

 

          这个类的泛型方法如下:

[delphi] view plaincopy

  1. function TInftClass.GetMin: Integer;  
  2. begin  
  3.   if Assigned (val1) and Assigned (val2) then  
  4.     Result := min (val1.GetValue, val2.GetValue)  
  5.   else  
  6.     Result := 0;  
  7. end;  
  8.   
  9. procedure TInftClass.IncreaseByTen;  
  10. begin  
  11.   if Assigned (val1) and Assigned (val2) then  
  12.   begin  
  13.     val1.SetValue (val1.GetValue 10);  
  14.     val2.SetValue (val2.GetValue 10);  
  15.   end;  
  16. end;  

 

 

        有了如上的定义,我们可以这样使用这个泛型类(数值型参数,接着还有其他类型参数的):

[delphi] view plaincopy

  1. procedure TFormIntfConstraint.btnValueClick(Sender: TObject);  
  2. var  
  3.   iClass: TInftClass;  
  4. begin  
  5.   iClass := TInftClass.Create;  
  6.   try  
  7.     iClass.Set1 (TGetValue.Create (5));  
  8.     iClass.Set2 (TGetValue.Create (25));  
  9.     Log ('Average: IntToStr (iClass.GetAverage));  
  10.     iClass.IncreaseByTen;  
  11.     Log ('Min: IntToStr (iClass.GetMin));  
  12.   finally  
  13.     iClass.val1.Free;  
  14.     iClass.val2.Free;  
  15.     iCLass.Free;  
  16.   end;  
  17. end;  

 

 

 

         为了展现这个泛型类的灵活性,我又建立了一个完全不同的(对GetValue接口)的实现:

[delphi] view plaincopy

  1. // IGetValue 的第二种实现  TButton对象  
  2. TButtonValue class (TButton, IGetValue)  
  3. public  
  4.     function GetValue: Integer;  
  5.     procedure SetValue (Value: Integer);  
  6.     class function MakeTButtonValue  
  7.         Owner: TComponent; Parent: TWinControl): TButtonValue;  
  8. end;  

 

       

     ButtonValue中,生成按钮坐标位置(随机位置,在父对象中)的成员函数,这个和主题关系不大,所以收缩

[delphi] view plaincopy

  1. // ButtonValue 成员函数,用来生成按钮的坐标位置  
  2. class function TButtonValue.MakeTButtonValue(Owner: TComponent;  
  3.   Parent: TWinControl): TButtonValue;  
  4. begin  
  5.   Result := TButtonValue.Create(Owner);  
  6.   Result.Parent := Parent;  
  7.   Result.SetBounds(  
  8.     Random (Parent.Width), Random (Parent.Height),  
  9.     Result.Width, Result.Height);  
  10.   Result.Caption := 'btnv';  
  11. end;  

 

        ButtonVauleGetVauleSetValue实现:

[delphi] view plaincopy

  1. // ButtonValue 中实现GetValue SetValue  
  2. function TButtonValue.GetValue: Integer;  
  3. begin  
  4.   Result := Left;  
  5. end;  
  6.   
  7. procedure TButtonValue.SetValue(Value: Integer);  
  8. begin  
  9.   Left := Value;  
  10. end;  

 

 

       下面是第二种(按钮坐标)泛型类的使用:

[delphi] view plaincopy

  1. // 主窗体中测试第二种(按钮的位置)泛型调用  
  2. procedure TFormIntfConstraint.btnValueButtonClick(Sender: TObject);  
  3. var  
  4.   iClass: TInftClass;  
  5. begin  
  6.   iClass := TInftClass.Create;  
  7.   try  
  8.     iClass.Set1 (TButtonValue.MakeTButtonValue (self, ScrollBox1));  
  9.     iClass.Set2 (TButtonValue.MakeTButtonValue (self, ScrollBox1));  
  10.     Log ('Average: IntToStr (iClass.GetAverage));  
  11.     Log ('Min: IntToStr (iClass.GetMin));  
  12.     iClass.IncreaseByTen;  
  13.     Log ('New Average: IntToStr (iClass.GetAverage));  
  14.   finally  
  15.     iClass.Free;  
  16.   end;  
  17. end;  

 

http://download.csdn.net/detail/busintel/2654390  代码下载

原文地址:https://www.cnblogs.com/luckForever/p/7254533.html