Class 如何声明变量

Class 如何声明变量,class,variables,ancestor,descendant,Class,Variables,Ancestor,Descendant,我和一位同事一直在讨论如何在函数中声明变量 假设您有一个名为TStrings的类(为了便于解释,使用Delphi),它至少有一个抽象方法和一个名为TStringList的后代类,后者显然实现了抽象方法,但它没有引入您需要的、尚未在祖先中实现的任何其他类,如何声明TStringList类型的函数变量 这里有两个例子。哪一种被认为是更好的做法?为什么 procedure AddElements; var aList: TStringList; begin aList := TStringLi

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

假设您有一个名为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;

我的投票是第二种形式,即TStrings定义了一个契约/接口,更好地为其编码。

我的投票是第二种形式,即TStrings定义了一个契约/接口,更好地为其编码。

它是一个TStringList,因此您还应该将其声明为TStringList(第一个示例)。其他一切都可能使您或稍后阅读代码的其他人感到困惑。

它是一个TStringList,因此您还应该将其声明为TStringList(第一个示例)。其他一切都可能让您或稍后阅读代码的其他人感到困惑。

我想说,这取决于您是否希望将TStringList更改为实现tstring的其他内容。如果您不希望它发生变化,那么使用TStringList并访问TStringList中单独存在的特殊功能(估计情况并非如此)。如果您预期它可能会更改,请将其声明为tstring并坚持使用“安全”方法


在这种情况下,我会说这不重要。见鬼,您可能会更改变量声明,但无论如何都不会更改。所以,使用你最喜欢的任何一个-这是一个偏好的问题。

我想说,这取决于你是否期望TStringList可能会被更改为其他实现tstring的东西。如果您不希望它发生变化,那么使用TStringList并访问TStringList中单独存在的特殊功能(估计情况并非如此)。如果您预期它可能会更改,请将其声明为tstring并坚持使用“安全”方法


在这种情况下,我会说这不重要。见鬼,您可能会更改变量声明,但无论如何都不会更改。所以,选择你最喜欢的——这是一个偏好的问题。

我同意施纳德的观点

TStringList比TStrings(一个抽象类)有更多的属性和方法。除非使用强制转换,否则使用TStrings变量禁止使用这些成员。但在我看来,这让事情变得更糟

可以在函数参数中使用tstring

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

或者作为一种财产。但是如果将局部变量和字段标记为实数类型,则它们的用途更广泛。

我同意Schnaader的观点

TStringList比TStrings(一个抽象类)有更多的属性和方法。除非使用强制转换,否则使用TStrings变量禁止使用这些成员。但在我看来,这让事情变得更糟

可以在函数参数中使用tstring

procedure TMyClass.MyMethod(const AList: TStrings);
begin
end;
或者作为一种财产。但如果局部变量和字段被标记为其真实类型,则它们的用途更广泛。

这取决于

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

例如:

Collection list = new ArrayList();
[loop] list.add(someItem); [end loop]
等等
为什么?它允许通过最小化更改的影响来更改实现(在某些情况下是一个细节:某些实现更适合某些用途(队列、链表、堆栈…),因此它可能主要是一个速度/内存问题)

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

另一个优点:当一个方法需要一个集合参数时,只要它只需要使用泛型方法,它就可以在更广泛的输入范围内工作。

这取决于

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

例如:

Collection list = new ArrayList();
[loop] list.add(someItem); [end loop]
等等
为什么?它允许通过最小化更改的影响来更改实现(在某些情况下是一个细节:某些实现更适合某些用途(队列、链表、堆栈…),因此它可能主要是一个速度/内存问题)

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


另一个优点:当一个方法需要一个集合参数时,只要它只需要使用泛型方法,它就可以在更大范围的输入上工作。

有人想添加一个语言标记,或者已经有了,但我不知道。有人想添加一个语言标记,或者已经有了,但我不知道。