Dziedziczenie klas - funkcje nie są dziedziczone

0

Witam.
Mam do napisania program liczący pola i obwody figur w którym mam użyć dziedziczenia klas. Jednak mam problem program dziedziczy jedynie zmienne a funkcji już nie.
Może to mały problem, ale niestety nie wiem jak go rozwiązać.

Oto kod

unit Unit2;

interface
type
  TCzwor = class
    a: integer;
    b: integer;
    c: integer;
    d: integer;
    function obwod: integer;
    constructor create (aa:integer;bb:integer;cc:integer;dd:integer);
  end;

type
  TProst = class (TCzwor)
    function pole: integer;
    constructor create (aa:integer;bb:integer);
  end;

type
  TKwad = class (TProst)
  constructor create (aa:integer);
  end;
implementation

function TCzwor.obwod: integer;
begin
  obwod:= a+b+c+d;
end;
constructor TCzwor.create (aa: integer; bb: integer; cc: integer; dd: integer);
begin
  a:=aa;
  b:=bb;
  c:=cc;
  d:=dd;
end;

function TProst.obwod: integer;
begin
  obwod:= 2*a+2*b;
end;

function TProst.pole: integer;
begin
  pole:= a*b;
end;
constructor TProst.create (aa:integer;bb:integer);
begin
  a:= aa;
  b:= bb;
  c:= a;
  d:= b;
end;

end. 

dodanie znacznika <code class="delphi"> - furious programming

0

I których funkcji "już nie" ?

0

Może zanim zaczniej dalej coś programować, zapoznaj się z poziomami dostępu do składowych klas.

1

W kodzie są błędy. Z dziedziczeniem funkcji Obwod kłopotu nie ma. Tylko że Ty ją drugi raz tak samo nazywasz w kolejnej klasie. Ogólnie kod żeby się kompilował bez błędów to raczej musi wyglądać jak ten poniżej. Ale wtedy obliczanie obwódu jest bez sensu na przykład dla klasy typu TProst. Ponieważ takowa nie ma elementów zmiennych c i d. Jeśli dobrze widzę. Przez co na przykład u mnie po podaniu w konstukrotrze 4 oraz 5. Otrzymałem 16. Czyli wynikowe śmieci są niestety "z tyłka wzięte" :/

Także poczytaj najpierw podstawy. Myślę, że w tym przypadku odnoszenie się do figur gemoetrycznych jako klas i stosowanie do nich klasy bazowej z której dziedziczą, w taki sposób jak pokazłeś jest złym pomysłem. Ponieważ każda klasa potomna ma inaczej liczone obwody i tak dalej. Klasa bazowa dobrze zaprojektowana w gotowym VCL to na przykład TWinControl. Czyli posiada na przykład Handle, koordynaty położenia. Z metod ma destruktor itp. I inne klasy po niej dziedziczą. A tutaj masz figury. No coż - nie za bardzo przemyślany imo przykład.

unit Unit2;

interface
type
  TCzwor = class
    a : integer;
    b : integer;
    c : integer;
    d : integer;
  public
    function obwod : integer;
    constructor create(aa : integer; bb : integer; cc : integer; dd : integer);
  end;

type
  TProst = class(TCzwor)
    function pole : integer;
    constructor create(aa : integer; bb : integer);
  end;

type
  TKwad = class(TProst)
    constructor create(aa : integer);
  end;

implementation

function TCzwor.obwod : integer;
begin
  obwod := a + b + c + d;
end;

constructor TCzwor.create(aa : integer; bb : integer; cc : integer; dd : integer);
begin
  a := aa;
  b := bb;
  c := cc;
  d := dd;
end;

function TProst.pole : integer;
begin
  pole := a * b;
end;

constructor TProst.create(aa : integer; bb : integer);
begin
  a := aa;
  b := bb;
  c := a;
  d := b;
end;

constructor TKwad.create(aa : integer);
begin
end;

end.
0

Zawsze można sobie zrobić abstrakcyjną metodę liczenia pola figury w klasie bazowej i ją potem przedefiniować w każdej klasie dziedziczącej; Ja bym to widział mniej więcej tak:

type
  { macierz do przechowania długości czterech boków figury }
  TQuadrangleSides: array [0 .. 3] of Cardinal;

type
  { bazowa klasa czworokątów }
  TQuadrangle = class(TObject)
  private
    FSides: TQuadrangleSides;
  public
    constructor Create(ASides: TQuadrangleSides);
  public
    function Perimiter(): Cardinal;
    function Area(): Cardinal; virtual; abstract;
  end;

type
  { bazowa klasa prostokątów }
  TRectangle = class(TQuadrangle)
  public
    constructor Create(AWidth, AHeight: Cardinal);
  public
    function Area(): Cardinal; override;
  end;

type
  { klasa kwadratu }
  TSquare = class(TRectangle)
  public
    constructor Create(ASide: Cardinal);
  public
    function Area(): Cardinal; override;
  end;

Nadmienić należy, że typ Integer nie jest najlepszym rozwiązaniem, bo długość dowolnego boku raczej nie może być ujemna; Zamiast tego można skorzystać np. z typu Cardinal, mogącego przechowywać liczby naturalne;

Pamiętać należy, że w konstruktorach klas TRectangle oraz TSquare należy wywołać konstruktory klas odziedziczonych z odpowiednimi parametrami, wywołując je za pomocą klauzuli Inherited.

0

Dzięki za pomoc, już sobie poradziłem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0