2017-02-06 19 views
1

私はDelphiとLazarusの両方でチュートリアルを行っています。私はDelphi 10.1 Berlin Update 2とLazarus 1.6.2を使用しています。Delphiで有効なコンストラクタがLazarusで失敗するのはなぜですか?

次のコンストラクタは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. 
+5

差分パラメータで同じコンストラクタ名を複製しているので、コンストラクタを 'reintroduce 'するか、' {$ mode delphi} 'を使う必要があります。 –

+0

応答をありがとう。私は{$ mode delphi}を試してみました。再導入は効果がなく、いずれもクラス名(Dog)をインスタンス変数として使用できません。 Delphiではすべてうまく動作しますが、これからはすべてをユニークに保ちます。 JavaとC#では、クラス名の後ろに小文字のクラスインスタンス変数を指定するのは、大文字と小文字が区別されるのでよくあることです。 –

答えて

3

これはどちら知っているとして、それは、コンパイラを混乱ので、あなたは、オブジェクトのメソッドのパラメータとオブジェクトのプロパティに同じ名前を使用してはならないのFreePascal /ラザロとの私の経験から。

ですから、このような何かにあなたのTDog.Constructor方法を変更する必要があります。私は単にAで、すべてのメソッドのパラメータを前に付けていること

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

注意してください。

メソッドパラメータとオブジェクトプロパティに同じ名前を付けると、コードをもっと混乱させるため、メソッドパラメータの名前付けについては、同様のアプローチを使用することをお勧めします。

デルファイは、オブジェクトのプロパティと同じ名前のメソッドパラメータを持つコードを処理できますが、他のコンパイラやオブジェクトパスカルの方言ではほとんど行いません。

PS:数年前、デルファイからFPC/Lazarusにコードの一部を移植しようとしたとき、まったく同じ問題が発生しました。私は300日以上のクラスで自分のコードをリファクタリングする2日間は問題ではないことを一日中知りました。

それ以来、私は自分の悪い習慣を変えようとしています。時にはメソッドのパラメータとプロパティに同じ名前を使用することがあります。

関連する問題