3

PHP言語で実装したものに似たものを作成する必要があります。

2つの静的メンバー変数を定義する基本クラスを作成したと仮定し、サブクラスはそれらを「オーバーライド」できる必要があるため、BaseClassで静的変数「someStatic」を定義し、DerivedClassにサブクラス化すると、 TDerivedOne.someStatic を呼び出すと、プログラムはその派生クラスから someStatic を表示する必要があります..しかし、Delphi の場合はそうではありません.私は間違いなく間違って実装しました..

とりあえず、変数が静的に宣言されていない別の設計アプローチを実装し、「セットアップ」と呼ばれる仮想抽象メソッドを作成しました。このセットアップはBaseClassコンストラクターで呼び出されますが、この設計ではオブジェクトを作成する必要があります最初に、必要な変数を取得する前に。

好奇心から、仮想静的変数を実装して「数回の入力を節約できるかどうか..」と思います。

これが問題のコードスニペットです

program Project1;

{$APPTYPE CONSOLE}


uses
    SysUtils;


type
    TBaseClass = class
      protected
        class var someStatic: string;

      public
        class function get: string; virtual;
    end;

    TDerived = class( TBaseClass )
      (*
      //if i uncomment this section, then the print bellow will print the Base's static var
      protected
        class var someStatic: string;
      *)
    end;

    TDerived2 = class( TBaseClass )
    end;

class function TBaseClass.get: string;
begin
    Result := someStatic;
end;


begin
    // ------If the class is defined per unit, this one should be on the initialization section
    TBaseClass.someStatic := 'base';
    TDerived.someStatic := 'derived';
    TDerived2.someStatic := 'derived2';
    // ------END OF INITIALIZATION

    try
        //i'm expecting this would print 'derived' but it prints 'derived2' :'(
        //i am using DelphiXE
        //apparently delphi treat the statics differently from that of php's
        writeln( TDerived.get );
        readln;
    except
        on E: Exception do
            writeln( E.ClassName, ': ', E.Message );
    end;

end.

乾杯 :)

4

2 に答える 2

0

すべての継承の SomeStatic は同じ場所を指すため、最後の設定が保持されます。
要件に最も近いアプローチは次のようになります。

type
    TBaseClass = class
      protected
        class var someStatic: string;
      public
        class function get: string; virtual;
        class Procedure _Set(const Value:String);virtual;
    end;

    TDerived = class( TBaseClass )
      protected
        class var someStatic: string;
      public
        class function get: string; override;
        class Procedure _Set(const Value:String);override;
    end;

    TDerived2 = class( TBaseClass )
      protected
        class var someStatic: string;
      public
        class function get: string; override;
        class Procedure _Set(const Value:String);override;
    end;

class function TBaseClass.get: string;
begin
    Result := someStatic;
end;


{ TDerived }

class function TDerived.get: string;
begin
    inherited;
    Result := someStatic;
end;

class procedure TDerived._Set(const Value: String);
begin
    SomeStatic := Value;
end;

{ TDerived2 }

class function TDerived2.get: string;
begin
    inherited;
    Result := someStatic;
end;

class procedure TDerived2._Set(const Value: String);
begin
  SomeStatic := Value;
end;

class procedure TBaseClass._Set(const Value: String);
begin
  SomeStatic := Value;
end;
于 2013-07-27T11:03:14.640 に答える