问题描述
我正在研究Delphi和Lazarus中的教程.我正在使用Delphi 10.1 Berlin Update 2和Lazarus 1.6.2.
I'm working through tutorials in both Delphi and Lazarus. I'm using Delphi 10.1 Berlin Update 2 and Lazarus 1.6.2.
以下构造函数可在Delphi中工作,但TDog
类中的构造函数在Lazarus中失败,并出现重复标识符"错误.
The following constructors work in Delp but the constructor in the TDog
class fails in Lazarus with a "duplicate identifier" error.
我搜索过的所有教程和论坛看起来都不是问题.
All tutorials and forums I have searched look like this shouldn't be a problem.
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.
推荐答案
根据我在FreePascal/Lazarus上的经验,您不应为对象方法参数和对象属性使用相同的名称,因为它会使编译器混淆哪个是哪个.
From my experience with FreePascal/Lazarus you should not use same names for object method parameters and object properties, because it confuses the compiler as to know which one is which.
因此,您应该将TDog.Constructor方法更改为如下形式:
So you should change your TDog.Constructor method into something like this:
constructor create(AName: String; ASize, AWeight, AEyes, ALegs,
ATeeth, ATail: integer; ACoat: String);
请注意,我只是在您的所有方法参数前面加上了A
.
Notice that I simply prefixed all your method parameters with A
.
事实上,我建议您到处都使用类似的方法来命名方法参数,因为方法参数和对象属性的名称相同也会使代码更加混乱.
In fact I recommend you use similar approach about naming method parameters everywhere because having same name for method parameters and object properties is also making code more confusing.
虽然Delphi能够处理具有与对象属性同名的方法参数的代码,但其他编译器和对象Pascal方言却没有.
While Delphi is capable of handling code which have method parameters with same names as object properties other compilers and Object Pascal dialects mostly don't.
PS:几年前,当我试图将某些代码从Delphi移植到FPC/Lazarus时,我遇到了完全相同的问题.我花了整整一天的时间才弄清楚问题出在哪里,更不用说两天的时间对300多个类进行代码重构了.
PS: When few years ago I tried to port some of my code from Delphi to FPC/Lazarus I ran into the exact same problem. I have spent whole day figuring out what the problem is not to mention two days refactoring my code with over 300 classes.
从那时起,我一直在试图改变我的坏习惯,即有时仍对方法参数和属性使用相同的名称.
And ever since then I'm trying to change my bad habit of still sometimes using same names for method parameters and properties.
这篇关于为什么在Delphi中有效的构造函数会在Lazarus中失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!