关于父类与子类的一点疑问、该如何处理

关于父类与子类的一点疑问、
(昨天自己去翻译一个C#的代码、那个泛型着实把我膈应了一把、好不容易改写完、也碰到一些小问题、我对于这些概念性的一直很模糊)

Delphi(Pascal) code

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  Aa = class(TObject)
    public
      constructor Create;
      destructor Destroy;
      function abc:Cardinal; //为了防止编译器优化掉循环
  end;

type
  Bb = class(Aa)
    public
      ss:TStringList;//用户占用内存方便观察
      constructor Create;
      destructor Destroy;
      procedure Free;
  end;
type
  TForm1 = class(TForm)
    btn1: TButton;
    btn2: TButton;
    btn3: TButton;
    btn4: TButton;
    btn5: TButton;
    btn6: TButton;
    btn7: TButton;
    btn8: TButton;
    procedure btn1Click(Sender: TObject);
    procedure btn2Click(Sender: TObject);
    procedure btn3Click(Sender: TObject);
    procedure btn4Click(Sender: TObject);
    procedure btn5Click(Sender: TObject);
    procedure btn6Click(Sender: TObject);
    procedure btn7Click(Sender: TObject);
    procedure btn8Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ Aa }

function Aa.abc: Cardinal;
begin
  Result:=Random(9999);
end;

constructor Aa.Create;
begin
  inherited;
end;

destructor Aa.Destroy;
begin
  inherited;
end;

{ Bb }

constructor Bb.Create;
begin
  inherited;
  ss:=TStringList.Create;
end;

destructor Bb.Destroy;
begin
  ss.Free;
  inherited;
end;
{如果自己写Free就需要这么写?
procedure Bb.Free;
begin
  if Self <> nil then
    Self.Destroy;
  Self:=nil;
end;
}
procedure TForm1.btn1Click(Sender: TObject);  //Create后不释放
var
  ii,rnd:Cardinal;
  k:Aa;
begin
  for ii := 0 to 99999 do
  begin
    k:=Aa.Create;
    rnd:=k.abc; //防止编译器把循环给优化掉
  end;

  ShowMessage(IntToStr(rnd) + #13 + '完成了');
  //通过观察内存使用量、大概每次占用1.7M内存没有释放
end;

procedure TForm1.btn2Click(Sender: TObject);
var
  ii,rnd:Cardinal;
  k:Aa;
begin
  for ii := 0 to 99999 do
  begin
    k:=Aa.Create;
    rnd:=k.abc;
    k.Destroy;
  end;

  ShowMessage(IntToStr(rnd) + #13 + '完成了');
  //循环完毕、基本内存使用量无变化(几十K的变化、忽略)
end;

procedure TForm1.btn3Click(Sender: TObject);
var
  ii,rnd:Cardinal;
  k:Aa;
begin
  for ii := 0 to 99999 do
  begin
    k:=Aa.Create;
    rnd:=k.abc;
    k.Free;
  end;

  ShowMessage(IntToStr(rnd) + #13 + '完成了');
  //循环完毕、基本内存使用量无变化(同调用Destroy方法)
end;

procedure TForm1.btn4Click(Sender: TObject);
var
  ii,rnd:Cardinal;
  k:Aa;
begin
  for ii := 0 to 99999 do
  begin
    k:=Aa.Create;
    rnd:=k.abc;
    FreeAndNil(k);
  end;

  ShowMessage(IntToStr(rnd) + #13 + '完成了');
  //循环完毕、基本内存使用量无变化(同调用Destroy方法)
end;

//***********Bb类测试************************************

procedure TForm1.btn5Click(Sender: TObject);
var
  ii,rnd:Cardinal;
  k:Bb;
begin
  for ii := 0 to 99999 do
  begin
    k:=Bb.Create;
    rnd:=k.abc; //防止编译器把循环给优化掉
  end;

  ShowMessage(IntToStr(rnd) + #13 + '完成了');
  //通过观察内存使用量、大概每次占用9M内存没有释放
end;
procedure TForm1.btn6Click(Sender: TObject);
var
  ii,rnd:Cardinal;
  k:Bb;
begin
  for ii := 0 to 99999 do
  begin
    k:=Bb.Create;
    rnd:=k.abc; //防止编译器把循环给优化掉
    k.Destroy;
  end;

  ShowMessage(IntToStr(rnd) + #13 + '完成了');
  //通过观察内存使用量、使用量基本无变化
end;

procedure TForm1.btn7Click(Sender: TObject);
var
  ii,rnd:Cardinal;
  k:Bb;
begin
  for ii := 0 to 99999 do
  begin
    k:=Bb.Create;
    rnd:=k.abc; {防止编译器把循环给优化掉}
    k.Free;
  end;

  ShowMessage(IntToStr(rnd) + #13 + '完成了');
  {通过观察内存使用量、每次有8M没有释放}
end;

procedure TForm1.btn8Click(Sender: TObject);
var
  ii,rnd:Cardinal;
  k:Bb;
begin
  for ii := 0 to 99999 do
  begin
    k:=Bb.Create;
    rnd:=k.abc; //防止编译器把循环给优化掉
    FreeAndNil(k);
  end;

  ShowMessage(IntToStr(rnd) + #13 + '完成了');
  //通过观察内存使用量、每次有8M没有释放
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  k:Bb;
begin
  k:=Bb.Create;
  ShowMessage(IntToStr(k.abc));
  {
  //第一种方法
  k.Free;
  //第二种方法
  FreeAndNil(k);
  //第三种方法
  k.Destroy;
  //第四种方法
  //k.Destroy;
  k:=nil;
  }
  ShowMessage(IntToStr(k.abc));
  //无论选择四种中的哪一种、依旧可以返回一个数值、这又是为什么呢?
end;

end.