Skocz do zawartości

[Delphi] Pytanie o dziedziczenie :)


Toster

Polecane posty

Jako ze dawno nie bylo zagadek... czas to naprawic :D Mamy koda + odpowiedzi:

 

TClass1 = class
  public
     fPole:    integer;
     constructor Create;
end;

TClass2 = class(TClass1)
  public
     fPole:    integer;
  constructor  Create;
end;


constructor TClass1.Create;
begin
  fPole := 1;
end;

constructor TClass2.Create;
begin
  inherited;
  fPole := 2;
end;


procedure test;
var
 c1: TClass1;
 c2: TClass2;
begin
 c2 := TClass2.create;
 c1 := c2;

 Writeln( c1.fPole, c2.fPole); 
end;

 

Wynikiem bedzie:

a) 11

B) 12

c) 22

d) 21

 

Kto wie ? :D

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

;P Nie ukrywając, że zaskoczony jestem :D

Ale moja odpowiedź na to jest taka:

Taka blokada przypisania jest dobrym rozwiązaniem jeżeli chcemy mieć dostęp do wartości "orginalnych" w klasie dziedziczonej... ;]

 

Wtedy zamiast deklarować to całe "c1" wystarczy dać TClass1(c2).fPole by mieć wartość pola "fPole" przed wywołaniem konstruktora z TClass2 :) który nadpisuje to pole.

 

A przypisać nie chce... bo jak by nie patrzeć :D TClass2 i TClass1 są różne (okiem kompilatora) ;)

Bo gdyby inaczej było :P to można by przypisać c2 := c1; a to wywoła brak zgodności klass :) mimo, że c2 też zawiera te same pola co c1 :D to jednak jest rozszerzoną wersją i nie taką samą... czyli przypisać się nie da.

 

To tak jak byś napisał 2 identyczne strukturą klasy z takimi samymi polami i metodami i próbował je nadpisać:

 

TClass1 = class
  public
     fPole:    integer;
     constructor Create;
end;

TClass2 = class
  public
     fPole:    integer;
  constructor  Create;

constructor TClass1.Create;
begin
  fPole := 1;
end;

constructor TClass2.Create;
begin
  inherited;
  fPole := 2;
end;


procedure test;
var
 c1: TClass1;
 c2: TClass2;
begin
 c2 := TClass2.create;
 c1 := c2;

 Writeln( c1.fPole, c2.fPole);
end;

 

A to nie jest możliwe (to nadpisanie takich samych klas) ;D

 

A na sam koniec... jak dla mnie to Twoje przypisanie to jak by "pominięty?" błąd kompilatora... ;] bo w takim razie jak nie przypisuje wartości pól z klasy dziedziczącej(TClass2) do klasy dziedziczonej(TClass1) to powinien wyskoczyć z błędem typu:

Incompatible types: 'TClass1' and 'TClass2'

jak to ma miejsce przy przepisaniu c2 := c1; :P albo przypisać i siedzieć cicho :D

 

Pozdro.

Prawdziwy programista wiesza sie wraz ze swoim programem.

Link do komentarza
Udostępnij na innych stronach

Z metodami inna sprawa niż z polami :P bo wystarczy dać "virtual" i "override" a nadpisywanie c1 := c2 jest możliwe... z polami takiej możliwości nie ma... :)

 

 


TClass1 = class
   procedure kupa; virtual;
 end;

 TClass2 = class(TClass1)
   procedure kupa; override;
 end;


var
 c1 : TClass1;
 c2 : TClass2;

procedure TClass1.kupa;
begin
 writeln('Klasa 1 kupa');
end;

procedure TClass2.kupa;
begin
 writeln('Klasa 2 kupa');
end;

procedure test;
begin
c2 := TClass2.Create;
c1 := c2;
c1.kupa;
c2.kupa;
end;

 

i co wyświetla ?

KOD

Klasa 2 kupa

Klasa 2 kupa

 

bez virtual i override wyświetli:

KOD

Klasa 1 kupa

Klasa 2 kupa

 

I z polami tego efektu nie ma... ;] virtual i override :P w moim D7 do pól się nie da przypisać :D nawet na siłę xD bo błąd wywala :)

 

 

Więc wytłumacz proszę :D co rozumiesz pod tymi słowami??:

 

... po prostu nastepuje przysloniecie pol

 

A odpowiedź na Twój 1 post to B czyli "12"

Prawdziwy programista wiesza sie wraz ze swoim programem.

Link do komentarza
Udostępnij na innych stronach

ogolnie mamy klase TClass1 ktora przedstawia pole np fPole.

Pozniej jak mamy klase TClass2 ktora dziedzyczy po class1 to znczy doslownie: wez wszystko z C1 i dodaj cos od siebie (jak programista doda)

 

a ze programista w klasie c2 dodal od siebie pole fPole to klasa C2 ma wszystko z C1 + fPole.

I do tej pory wszystko jest jasne i oczywiste ale okazuje sie ze fPole z C2 nazywa sie tak samo jak fPole z C1. Na pierwszy rzut oka wydaje sie ze kompiler po prostu polaczy te dwie deklaracje do kupy i juz. Ale jak sam zauwazyles nie ma przeciazania pol.... skoro nie przeciazasz to musisz przyslaniac. Dlaczego ? ano pokombinujcie z roznymi typami w klasie bazowej i dziedziczacej.... No bo co ma zrobic kompilator jak w pierwszej klasie bedzie Int a w drugiej String... Ni jak nie ma co z tym zrobic. No i jedyny problem w tym momemcie to "kontekst" wywolania. czy siegamy po zmienna z klasy bazowej czy z dziedziczacej co wychodzi na jaw w moim pytaniu.

 

Jak jeszcze nie do konca chwytasz to sproboj rozczaic bardzo podobny mechnizm przyslaniania zmiennych. np:

 


TKlaska = class
  private
     fPole: integer;
     procedure  SetPole(var pole, pole2: integer);
         pole := pole2;
     end;
  public
     property pole: integer read fPole write fPole;
end;

 

no i pytanie: w metodzie setPole do czego siegamy piszac 'pole' do argumentu metody czy do propertiesa klasy ?

 

PS.

W niektorych ide do C++/Javy ladnie to widac w debugerze, jak rozwiniesz obiekt jakiejs klasy to widac pola ktore ma podane w deklaracji klasy, natomiast to co ma z przodkow masz w osobnym nodzie inherited, jak rozwiniesz inherited to widac ladnie co odziedziczyles i ewentualnie kolejny inherited itd itd. w efekcie mozna podgldnac co jest przysloniete

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

Ok :) już rozumiem Twoje przysłonięcia :D

A co do pytania odnośnie procedury setPole to sprawa oczywista jest taka, że zmiana wartości zmiennej "pole" sięgać będzie do argumentu metody, nie do propertisa klasy :) Całą magię robi to słowo "var" co umożliwia przekazywanie parametrów przez referencje :) Bez niego odwołanie by się zmieniło do propertisa "pole" w klasie... ;]

Prawdziwy programista wiesza sie wraz ze swoim programem.

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...