2017-02-06 2 views
1

Je travaille sur des tutoriels à la fois dans Delphi et Lazarus. J'utilise Delphi 10.1 Berlin Update 2 et Lazarus 1.6.2.Pourquoi un constructeur valide dans Delphi échoue dans Lazarus?

Les constructeurs suivants fonctionnent dans Delphi, mais le constructeur de la classe TDog échoue dans Lazarus avec une erreur "identificateur en double".

Tous les tutoriels et les forums que j'ai cherché ressemblent à ceci ne devrait pas être un problème.

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. 
+5

Puisque vous dupliquez le même nom de constructeur avec des paramètres de différence, vous devez soit réintroduire le constructeur, soit utiliser '{$ mode delphi}'. –

+0

Merci pour les réponses. J'ai essayé le {$ mode delphi} et ça a fait l'affaire. reintroduce n'a eu aucun effet, et aucun ne permettrait d'utiliser le nom de la classe (Dog) comme variable d'instance. Même si tout fonctionne bien dans Delphi, je vais garder tout unique à partir de maintenant. Il semble juste commun dans Java & C# de nommer les variables d'instance de classe en minuscules après le nom de la classe car les langues sont sensibles à la casse. –

Répondre

3

De mon expérience avec FreePascal/Lazarus vous ne devriez pas utiliser les mêmes noms pour les paramètres de la méthode d'objet et propriétés de l'objet, car il confond le compilateur à savoir lequel est lequel.

Donc, vous devriez changer votre méthode de TDog.Constructor en quelque chose comme ceci:

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

Notez que je simplement préfixés tous vos paramètres de méthode avec A.

En fait, je vous recommande d'utiliser une approche similaire sur les paramètres de méthode de nommage partout parce que le fait d'avoir le même nom pour les paramètres de méthode et les propriétés d'objet rend le code plus confus. Alors que Delphi est capable de gérer du code avec des paramètres de méthode ayant les mêmes noms que les propriétés d'objet, les autres compilateurs et les dialectes Object Pascal ne le font pas. PS: Quand il ya quelques années, j'ai essayé de porter une partie de mon code de Delphi à FPC/Lazarus j'ai rencontré exactement le même problème. J'ai passé toute la journée à comprendre ce que le problème est de ne pas mentionner deux jours refactoring mon code avec plus de 300 classes.

Et depuis, j'essaie de changer ma mauvaise habitude de toujours parfois utiliser les mêmes noms pour les paramètres et propriétés de la méthode.