views:

592

answers:

1

In one file, I have a baseclass with a ID-property:

type
  TBase = class(TObject)  
  private  
    FID: integer;  
  public  
    property ID: integer read FID write SetID;  
  end;

In a second file, I have another class, descending from TBase. By accident, or ignorance or what ever, a new property/field with the same name as an exsisting property/field was made.

type
  TSub = class(TBase)
  private
    FID: Longword;
  public     
    property ID: Longword read FID write FID;
  end;

The second ID-fields is of course renamed, but why does the compiler allow this?
When accessing ID in code - which ID-field is used?

+9  A: 

Delphi allows this to 'hide' your old properties and introduce properties with the same name that operate differently. I've used this for example to create my own typesafe TList descendants for a specific class or record:

type
  TMyList = class(TList)
  private
    function GetItem(Index: Integer): TMyObject;
    procedure SetItem(Index: Integer; Value: TMyObject);
  public
    property Items[Index: Integer]: TMyObject read GetItem write SetItem;
  end;

  function TMyList.GetItem(Index: Integer): TMyObject;
  begin
    Result := TMyObject(inherited Items[Index]);
  end;

  procedure SetItem(Index: Integer; Value: TMyObject);
  begin
    inherited Items[Index] := Value;
  end;

Ofcourse, with Delphi 2009 and generics, it's a lot easier now.

Which ID you are accessing depends on the place you are calling ID from.

procedure TSub.Foo;
begin
  ID := 5; //TSub.ID
  inherited ID := 6 //TBase.ID
end;

procedure TBase.FooBar;
begin
  ID := 5; //TBase.ID
end;

var
  Sub: TSub;
  Base: TBase;
begin
  Sub := TSub.Create;
  try
    Sub.ID := 1; //assign 1 to TSub.ID
    TBase(Sub).ID := 2; //assign 2 to TBase.ID
    WriteLn(Sub.ID); //writes 1
    WriteLn(TBase(Sub).ID); //writes 2
    Base := Sub;
    WriteLn(Base.ID); //writes 2
  finally
    Sub.Free;
  end;
end;
The_Fox
Please don't use "override" to describe this. That suggests there's something related to virtual functions and polymorphism, but there isn't. A variable of type TList will always access TList's Items property, even when the variable holds an instance of your TMyList class. A better word is "hide."
Rob Kennedy
You're right, I changed my answer a little bit.
The_Fox
Reintroduce is a better word for it.
The_Fox