Delphi - 必须的一致.

本文通过一个具体的示例,探讨了在Delphi中处理接口转换时容易忽视的问题,并详细解释了为何在从接口列表中取出对象并进行转换时,必须遵循正确的类型转换步骤。

大家好,我是HuangJacky,技术交流.
这个是在工作发现的一个问题,而且是很久的问题了.当时已经写成文章了.但是(往往时常都有这个但是)系统挂了,文章还没有发出来.
好,赶紧发出来.

首先还原下问题:(这个 插件居然没有Pascal)

   1: //首先定义具有继承关系的接口
   2:   IBase = interface
   3:     procedure TalkBase;
   4:   end;
   5:  
   6:   IDerive = interface(IBase)
   7:     procedure TalkDerive;
   8:   end;
   9:   //实现的类
  10:   TBase = class(TInterfacedObject, IBase)
  11:     procedure TalkBase;
  12:   end;
  13:  
  14:   TDerive = class(TBase, IDerive)
  15:   private
  16:     FTest: Integer;
  17:   public
  18:     constructor Create();
  19:     procedure TalkBase;
  20:     procedure TalkDerive;
  21:   end;

类得实现.

   1: { TDerive }
   2:  
   3: constructor TDerive.Create;
   4: begin
   5:   FTest:= 55;
   6: end;
   7:  
   8: procedure TDerive.TalkBase;
   9: begin
  10:   ShowMessage('Derive say base');
  11: end;
  12:  
  13: procedure TDerive.TalkDerive;
  14: begin
  15:   ShowMessage('Derive');
  16: end;
  17:  
  18: { TBase }
  19:  
  20: procedure TBase.TalkBase;
  21: begin
  22:   ShowMessage('Base');
  23: end;

现在我们有一个列表,列表里面可以装这些接口的:

   1: procedure TForm2.Add(Obj: IBase);
   2: begin
   3:   FList.Add(Pointer(Obj))
   4: end;

是吧,这样列表里面都是放的接口.我们来看看使用的代码:

   1: procedure TForm2.btnTestClick(Sender: TObject);
   2: begin
   3:   //加两个
   4:   A:= TDerive.Create;
   5:   Add(A);
   6:   A:= TDerive.Create;
   7:   Add(A);
   8:   //使用
   9:   A:= TDerive(FList[0]);
  10:   ShowMessage(IntToStr(A.FTest));//我们预期是55
  11: end;

可是结果是怎么样的呢?
image
为什么是这么多呢?
后来我发现我们加进去的是接口IBase而我们使用的时候是直接转化TDerive.中间少了一步转换pointer->IBase.好的代码改一下:

   1: //使用
   2:   A:= TDerive(IBase(FList[0]));
   3:   ShowMessage(IntToStr(A.FTest));//我们预期是55

结果:image .正确了.
这里说明了什么?TList里面我们加进去的是什么,使用的时候就要先转换成加进去时候的类型后才能再转换成其他类型.
原因呢?
这个是因为Delphi中对象的内存组织决定的.
这个我明天说.现在得睡觉了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值