一个关于接口的问题?请教! ( 积分: 50 )

  • 主题发起人 主题发起人 czj_earth
  • 开始时间 开始时间
C

czj_earth

Unregistered / Unconfirmed
GUEST, unregistred user!
功能:
声明一个接口IMeter, 类TLot1RecordClass 实现接口,
全局函数GetMeterDataInterface返回创建的对象,并以(IMeter接口形式返回)
uMain单元中调用GetMeterDataInterface创建对象,为属性赋值
obj将新创建的对象转型为: TLot1RecordClass类,调用属性值, 返回值不正确.
why?


//接口声明单元
unit uMeterInteface

type
IMeter = interface //电表(种类不同,各种电表必须遵守和实现本接口)接口申明
['{98A7CE54-29FD-4093-8B2D-0625AE49072D}']
function GetMeterNO: Integer;
procedure SetMeterNO(Value: Integer);
property MeterNO: Integer read GetMeterNO write SetMeterNO;
....

end;
function GetMeterDataInterface: IMeter;

implementation
uses ulot1

function GetMeterDataInterface: IMeter;
begin
Result := Tlot1Recordclass.Create;
end;

uLot1

TLot1RecordClass = class(TInterfacedObject, IMeter)
private
FmeterNo: integer;
...
procedure SetMeterNO(Value: integer);
function GetMeterNO: integer;
public
property MeterNO: integer read GetMeterNO write SetMeterNO

end;
function TLot1RecordClass.GetMeterNO: integer;
begin
result := FMETERNO;
end;
procedure TLot1RecordClass.SetMeterNO(Value: integer);
begin
FMETERNO := Value;
end;

uMain //测试单元
private
FILot1: IMeter;
...


procedure TForm1.Button2Click(Sender: TObject);
var
obj: TLot1RecordClass;
begin
FILot1:= GetMeterDataInterface
//接口对象
if FILot1 <> nil then
begin
FILot1.MeterNO:= 1000;
showmessage(Inttostr(FILot1.MeterNo))
//显示1000

obj:= TLot1RecordClass(FILot1);
showmessage(Inttostr(obj.MeterNo)); //显示不确定数
MeterObject.IIMeter:= FILot1;
end;

end;
 
功能:
声明一个接口IMeter, 类TLot1RecordClass 实现接口,
全局函数GetMeterDataInterface返回创建的对象,并以(IMeter接口形式返回)
uMain单元中调用GetMeterDataInterface创建对象,为属性赋值
obj将新创建的对象转型为: TLot1RecordClass类,调用属性值, 返回值不正确.
why?


//接口声明单元
unit uMeterInteface

type
IMeter = interface //电表(种类不同,各种电表必须遵守和实现本接口)接口申明
['{98A7CE54-29FD-4093-8B2D-0625AE49072D}']
function GetMeterNO: Integer;
procedure SetMeterNO(Value: Integer);
property MeterNO: Integer read GetMeterNO write SetMeterNO;
....

end;
function GetMeterDataInterface: IMeter;

implementation
uses ulot1

function GetMeterDataInterface: IMeter;
begin
Result := Tlot1Recordclass.Create;
end;

uLot1

TLot1RecordClass = class(TInterfacedObject, IMeter)
private
FmeterNo: integer;
...
procedure SetMeterNO(Value: integer);
function GetMeterNO: integer;
public
property MeterNO: integer read GetMeterNO write SetMeterNO

end;
function TLot1RecordClass.GetMeterNO: integer;
begin
result := FMETERNO;
end;
procedure TLot1RecordClass.SetMeterNO(Value: integer);
begin
FMETERNO := Value;
end;

uMain //测试单元
private
FILot1: IMeter;
...


procedure TForm1.Button2Click(Sender: TObject);
var
obj: TLot1RecordClass;
begin
FILot1:= GetMeterDataInterface
//接口对象
if FILot1 <> nil then
begin
FILot1.MeterNO:= 1000;
showmessage(Inttostr(FILot1.MeterNo))
//显示1000

obj:= TLot1RecordClass(FILot1);
showmessage(Inttostr(obj.MeterNo)); //显示不确定数
MeterObject.IIMeter:= FILot1;
end;

end;
 
各位大哥,帮助解释一下,
我输出FILot1和obj的地址时,他们是同一对象,
为什么转型后obj对象不正确呢?
 
可以这么认为.
TLot1RecordClass包含了IMeter.也就是IMeter是TLot1RecordClass某一部分的标准说明.
供外部使用.将IMeter转成TLot1RecordClass好象有点...
如果有另一个类也实现了IMeter,如TLot2RecordClass.那么能否实现
IMeter1 := TLot1RecordClass.Create;
Lot2 := TLot2RecordClass(IMeter1);

将你的程序修改成

var
obj: TLot1RecordClass;
begin
obj := TLot1RecordClass.Create;
FILot1 := obj;
FILot1.MeterNo := 1000;
showmessage(Inttostr(obj.MeterNo));
end;
 
还是不太理解,
那位大哥有关于接口方面的资料,
给小弟一份,
万分感谢!
 
呵呵!czj_earth你的问题不仅仅是INTERFACE的问题,而是OOP的问题;
症结在:
A is a B
B := A 正确
A := B 不一定正确
也就是向上转换和向下转换的问题
TLot1RecordClass 继承了 IMeter
所以 TLot1RecordClass is a Imeter
obj: TLot1RecordClass
FILot1: IMeter
意味 obj is a FILot1
FILot1 := obj 正确
obj := FILot1 不&quot;一定&quot
正确
希望能给你一点帮助
如果仍然有不明白的地方,请联络QQ:5040071
 
谢谢sanmaotuo 和wlmmlw
 
多人接受答案了。
 
后退
顶部