为什么Delphi中的有效构造函数在Lazarus中失败?

时间:2017-02-06 17:29:00

标签: delphi lazarus

我正在学习Delphi和Lazarus的教程。我使用的是Delphi 10.1 Berlin Update 2和Lazarus 1.6.2。

以下构造函数在Delphi中工作,但TDog类中的构造函数在Lazarus中失败,并且带有"重复的标识符"错误。

我搜索过的所有教程和论坛看起来都不应该成为问题。

unit Animal;

interface

uses
  classes;

type
  TAnimal = class
    private
      FName: String;
      FBrain: Integer;
      FBody: Integer;
      FSize: Integer;
      FWeight: Integer;
    public
      constructor create(Name: String; Brain, Body, Size, Weight: Integer);

      procedure Eat; virtual;

      property Name: String read FName;
      property Brain: Integer read FBrain;
      property Body: Integer read FBody;
      property Size: Integer read FSize;
      property Weight: Integer read FWeight;
  end;

implementation

constructor TAnimal.create(Name: String; Brain, Body, Size, Weight: Integer);
begin
  FName:= Name;
  FBrain:= Brain;
  FBody:= Body;
  FSize:= Size;
  FWeight:= Weight;
end;

procedure TAnimal.Eat;
begin
  Writeln('TAnimal.eat called');
end;

end.

unit Dog;

interface

uses
  classes,
  Animal;

type

TDog = class (TAnimal)
  private
    FEyes: Integer;
    FLegs: Integer;
    FTeeth: Integer;
    FTail: Integer;
    FCoat: String;

    procedure Chew;
  public
    constructor create(Name: String; Size, Weight, Eyes, Legs,
     Teeth, Tail: integer; Coat: String);

  procedure Eat; override;


end;

implementation

//following fails in Lazarus

constructor TDog.create(Name: String; Size, Weight, Eyes, Legs,
     Teeth, Tail: integer; Coat: String);

//this works, changing implementation also 
//constructor Create(aName: String; aSize, aWeight, Eyes, Legs,
//     Teeth, Tail: integer; Coat: String); 

begin
  inherited Create(Name, 1, 1, Size, Weight);
  FEyes:= Eyes;
  FLegs:= Legs;
  FTeeth:= Teeth;
  FTail:= Tail;
  FCoat:= Coat;
end;

procedure TDog.Chew;
begin
  Writeln('TDog.chew called');
end;

procedure TDog.Eat;
begin
  inherited;
  Writeln('TDog.eat called');
  chew;
end;

end.

1 个答案:

答案 0 :(得分:3)

根据我使用FreePascal / Lazarus的经验,你不应该为对象方法参数和对象属性使用相同的名称,因为它会使编译器混淆知道哪一个是哪个。

因此,您应该将TDog.Constructor方法更改为以下内容:

constructor create(AName: String; ASize, AWeight, AEyes, ALegs,
 ATeeth, ATail: integer; ACoat: String);

请注意,我只是使用A为您的所有方法参数添加前缀。

事实上,我建议您使用类似的方法来命名方法参数,因为方法参数和对象属性具有相同的名称也会使代码更加混乱。

虽然Delphi能够处理具有与对象属性相同名称的方法参数的代码,但其他编译器和Object Pascal方言通常不会。

PS:几年前我试图将我的一些代码从Delphi移植到FPC / Lazarus时遇到了同样的问题。我花了一整天的时间搞清楚问题是什么,更不用说两天用300多个课程重构我的代码了。

从那时起,我一直试图改变我的坏习惯,有时仍然使用相同的方法参数和属性名称。