unit uObjects;

interface

uses
  SysUtils, Classes;

type
  TBase = class(TObject)
  private
    { Private declarations }
    FName : String;
    FHash : Cardinal;
  protected
    procedure SetName(const sName : String);
    procedure SetHash(const cHash : Cardinal);
  public
    { Public declarations }
    constructor Create; overload;
    function toString : String;
    function hashCode : String;
    function getBothID : String; overload; virtual;
    function DisappearRoutine1 : String; overload;
    function DisappearRoutine2 : String;
    function DisappearRoutine3 : String; overload; virtual;
    function DisappearRoutine3(const sName : String) : String; overload; virtual;
  end;

  TDerived = class(TBase)
  private
    { Private declarations }
    FDate : Variant;
  public
    { Public declarations }
    constructor Create(const sName : String); overload;
    constructor Create(const sName : String; const cHash : Cardinal); overload;
    function getBothID(const iDefault : Integer = 0) : String; reintroduce; overload;
    function getBothID(const sSaperator : String) : String; reintroduce; overload;
    function DisappearRoutine1(const sName : String) : String; overload;
    function DisappearRoutine2(const sName : String) : String;
    function DisappearRoutine3 : String; reintroduce; overload;
    function DisappearRoutine3(const sName : String) : String; reintroduce; overload;
    function PureMethod : String;
  published
    function MyMethod1 : String;
    procedure MyMethod2;

    property sDate : Variant read FDate write FDate;
  end;

  TDemo = class(TComponent)
  private
    FDate: Variant;
  published
    function MyMethod1 : String;
    procedure MyMethod2;

    property sDate : Variant read FDate write FDate;
  end;

implementation

{ TBase }

constructor TBase.Create;
begin
  FName := 'NoName';
  FHash := 0;
end;

function TBase.DisappearRoutine1 : String;
begin
  Result := 'TBase.DisappearRoutine1';
end;

function TBase.DisappearRoutine2: String;
begin
  Result := 'TBase.DisappearRoutine2';
end;

function TBase.DisappearRoutine3: String;
begin
  Result := 'TBase.DisappearRoutine3';
end;

function TBase.DisappearRoutine3(const sName: String): String;
begin
  Result := 'TBase.DisappearRoutine3' + sName;
end;

function TBase.getBothID: String;
begin
  Result := FName + IntToStr(FHash);
end;

function TBase.hashCode: String;
begin
  Result := IntToStr(FHash);
end;

procedure TBase.SetHash(const cHash: Cardinal);
begin
  if (cHash <> FHash) then
    FHash := cHash;
end;

procedure TBase.SetName(const sName: String);
begin
  if (sName <> Fname) then
    FName := sName;
end;

function TBase.toString: String;
begin
  Result := FName;
end;

{ TDerived }

constructor TDerived.Create(const sName: String);
begin
  inherited Create;
  SetName(sName);
end;

constructor TDerived.Create(const sName : String; const cHash: Cardinal);
begin
  inherited Create;
  SetName(sName);
  SetHash(cHash);
end;

function TDerived.getBothID(const iDefault : Integer) : String;
begin
  Result := toString + ' : ' + hashCode;
end;

function TDerived.DisappearRoutine1(const sName: String) : String;
begin
  Result := 'TDerived.DisappearRoutine1';
end;

function TDerived.getBothID(const sSaperator: String): String;
begin
  Result := toString + sSaperator + hashCode;
end;

function TDerived.DisappearRoutine2(const sName: String): String;
begin
  Result := 'TDerived.DisappearRoutine2';
end;

function TDerived.DisappearRoutine3: String;
begin
  Result := 'TDerived.DisappearRoutine3';
end;

function TDerived.DisappearRoutine3(const sName: String): String;
begin
  Result := 'TDerived.DisappearRoutine3' + sName;
end;

function TDerived.MyMethod1: String;
begin
  Result := 'I am pure Virtual Method!';
end;

procedure TDerived.MyMethod2;
begin
  MyMethod1;
end;

function TDerived.PureMethod: String;
begin
  Result := 'Pure Method!';
end;

{ TDemo }

function TDemo.MyMethod1: String;
begin
  Result := 'I am pure Virtual Method1!';
end;

procedure TDemo.MyMethod2;
begin
  MyMethod1;
end;

end.
