如何声明变量

时间:2008-12-09 11:10:39

标签: class variables ancestor descendant

我的一位同事和我一直在讨论如何在函数中声明变量。

假设你有一个名为TStrings的类(为了解释起见使用Delphi),它至少有一个抽象方法和一个名为TStringList的后代类,它显然实现了抽象方法,但是它没有引入你需要的其他东西。已经在祖先中实现了,你如何声明一个TStringList类型的函数变量?

以下是两个例子。这被认为是更好的做法,为什么?

procedure AddElements;
var
  aList: TStringList;
begin
  aList := TStringList.Create;
  try
    aList.Add('Apple');
    aList.Add('Pear');
  finally
    aList.free;
  end;
end;

procedure AddElementsII;
var
  aList: TStrings;
begin
  aList := TStringList.Create;
  try
    aList.Add('Apple');
    aList.Add('Pear');
  finally
    aList.free;
  end;
end;

5 个答案:

答案 0 :(得分:1)

它是一个TStringList,因此您还应将其声明为TStringList(第一个示例)。其他所有内容都会让您或其他人稍后阅读这些代码。

答案 1 :(得分:0)

我的投票是第二种形式 - 想法是TStrings定义合同/接口,并且更好地为它们编码。

答案 2 :(得分:0)

我会说这取决于你是否期望TStringList是否可以改为实现TStrings的其他东西。如果您不希望它发生更改,请使用TStringList并访问仅在TStringList中的特殊功能(猜测不是这种情况)。如果您希望它可能会发生变化,请将其声明为TStrings并坚持使用“安全”方法。

在这个具体案例中我会说没关系。天啊,你可能会改变变量声明,但无论如何都不会改变。因此,请使用您最喜欢的方式 - 这是一个偏好问题。

答案 3 :(得分:0)

我同意Schnaader。

TStringList具有更多属性和方法,即TStrings(它是一个抽象类)。使用TStrings变量禁止使用这些成员unles使用强制转换。但是,我认为这会使事情变得更糟。

您可以在函数参数中使用TStrings。

procedure TMyClass.MyMethod(const AList: TStrings);
begin
end;

或作为财产。但是,如果局部变量和字段的真实类型被标记,那么它们就会更加通用。

答案 4 :(得分:0)

这取决于......

在Java中,我经常看到使用可用的最高抽象级别进行声明的建议,尽管它通常适用于接口。

例如:

Collection list = new ArrayList();
[loop] list.add(someItem); [end loop]

等。
为什么?它允许更改实现(在某些情况下的细节:某些实现更适合某些用法(队列,链表,堆栈......),因此它可能主要是速度/内存问题)通过最小化更改的影响。

当然,如果您使用特定于实现的方法,则必须在声明中更具体。

另一个优点:当一个方法需要一个Collection参数时,只要它只需要使用泛型方法,它就可以处理更广泛的输入。