Klasa Abstrakcyjna?

0

Witam. Mam pytanie odnosnie deklarowania klas. Od razu podam przyklad:

 TKlasa = class abstract
   procedure Boom; 
 end;

Niedowno zauwazylem ze mona zadeklawoac tak klase i myslalem ze jest to zwykla klasa abstrakcyjna jak np. w c++. W tym problem ze ten kod jest niepoprawny poniewaz procedure "Boom" musi byc zdefiniowana. I moje pytanie brzmi: Czym jest TKlasa gdy zadeklaraujemy ja jako "class abstract"?, czy rozni sie ona w jakis sposob z normalna definicja "class"? i do czego sluzy konkretnie? Szukalem w internecie ale nic nie znalazlem konkretnego , myslalem ze tak wyglada klasa abstrakcyjna w Delphi NET ale i tam musze zdefiniowac procedure. Z gory dzieki za odpowiedz.

btw. mam jeszcze jedno pytanie odnosnie slowa kluczowego "final", do czego sluzy, kiedy sie przydaje itp. Wyglada ona tak:

TKlasa = class
  procedure Foo; virtual; final;
end;

Jescze raz dzieki. ;-)

0

abstract w odniesieniu do metody oznacza, że metoda ta nie ma implementacji (tę dopisuje się w klasach potomnych), zaś w odniesieniu do klasy oznacza, że nie można wywołać w programie obiektu (instancji) takiej klasy. Procedura, która nie jest oznaczona jako abstract musi mieć implementację, niezależnie od tego, jakiego typu jest dana klasa, dla porównania:

 TKlasa = class abstract
   procedure Boom; virtual; abstract;
 end;

virtual oznacza, że dana metoda może mieć inną implementację w klasach potomnych, zaś w zestawieniu z final oznacza, że dana metoda nie może być zastąpiona w klasach potomnych (choć przodkowie danej klasy mogli mieć taką możliwość)

0

Dzieki o abstrakcji wiedzialem ale nie w odniesniu do klasy i sorki ale nadal nie zabardzo rozumiem :(. Moze moglbys jaki przyklad podac albo konkretne zastosowanie. Dzieki.

0

Szczegóły zawsze możesz znaleźć w Helpie.
Instancję (obiekt) zwykłej klasy możesz wywołać używając konstruktorów

Klasa:= TKlasa.Create;

W ten sposób instancji zostaje przydzielona pamięć, i można wykonywać na niej działania. W przypadku klas abstraktowych takiej możliwości nie ma. Klasa abstraktowa może być (innego zastosowania nie widzę) klasą, po której będą dziedziczyć inne klasy potomne. Potomkowie (zwykłe klasy) będą mogły być wywołane w kodzie programu tak, jak to napisałem powyżej, zaś przodek nie (coś w rodzaju zabezpieczenia przed użyciem danej klasy). Wszystkie metody, które nie są oznaczone jako abstraktowe muszą posiadać implementację, niezależnie od tego czy dotyczą one klasy abstraktowej czy nie:

TKlasa = class abstract  // tej klasy nie mozna wywołać
  procedure Boom; virtual; abstract;  // nie potrzeba implementacji
  procedure Crash; // potrzebna implementacja
end;

TInnaKlasa = class(TKlasa)
  procedure Boom; override;// teraz potrzebna implementacja
  // procedura Crash i jej implementacja została odziedziczona
end

I teraz:

Klasa:= TKlasa.Create; // czegoś takiego nie można zrobić

  { poniższy kod jest prawidłowy }

InnaKlasa:= TInnaKlasa.Create;
InnaKlasa.Boom;
InnaKlasa.Crash;

Co do final to nie jestem pewien czy to tak działa, bo nigdy tego nie używałem, ale:

TJeszczeInnaKlasa = class(TInnaKlasa)
  procedure Boom; virtual; final;
end;

TKompletnieInnaKlasa = class(TJeszczeInnaKlasa)
  // nie można zmienić implementacji procedury Boom
end;

Niech mnie ktoś poprawi, jeśli coś pochrzaniłem

0

Wiec wynika z tego ze dobrze rozumialem, ale mialem watpilowasci bo jakos gdy zrobie wlasnie tak:

Klasa:= TKlasa.Create; // czegoś takiego nie można zrobić

  { poniższy kod jest prawidłowy }

InnaKlasa:= TInnaKlasa.Create;
InnaKlasa.Boom;
InnaKlasa.Crash;

to dziala, moge wywloac konstructora i moge miec dostep do klasy Crash (Boom jest abstarkcyjna wiec z nia niec nie zrobie :) ). Bo teraz w tym wypadku nie widze roznicy miedzy TKlasa = class, a TKlasa = class abstract. Niewiem czy dalej bladze we wlasnych myslach :D, ale mozliwe ze bylo tak dawniej w delphi (a moze jest tak tylko na pltformie NET?) a teraz poptostu to NIE MA znaczenia. Niewiem moze to kotos potwierdzic?. Jescze raz Dzieki Luc.

0

hmmm... trochę namieszałeś
Boom i Crash to metody, a nie klasy.
Przytoczę cytat z helpa:
"If a class is marked abstract, then it cannot be instantiated directly using the Create constructor"
Czyli, że

Klasa:= TKlasa.Create;

nie powinno działać, jeśli klasa TKlasa jest oznaczona jako abstract, podobnie jak nie można wywołać metody abstrakcyjnej (nie ma ona implementacji - próba wywołania zakończy się wystąpieniem wyjątku)
Co do .NET, to:
"When a method is declared as abstract in an ancestor class, you should surface it (by redeclaring and implementing it) in any descendant component before you use the new component in applications. On the Win32 platform, Delphi can create instances of a class that contains abstract members. This is not recommended, however, and it is not allowed on the .NET platform".

0

sorki dobrze mysalem ale zle napisalem :).
Okej niewiem dlaczego ale ja moge wywloac konstruktor klasy zadeklarowanej poprzez "class abstract" i uzywac jej metod.

dla mnie taki kod dziala:

TKlasa = class abstract  
  procedure Crash; //
end;

procedure TKlasa.Crash;
begin
  ShowMessage('TKlasa.Crash');
end;

var
  Klasa: TKlasa;

begin
  Klasa := TKlasa.Create; //dziala bez problemy
  try
    Klasa.Crash; // i tutaj tez bez problemu
  finally
    Klasa.free
  end;

Takze cos jest nietak moim zdaniem badz ciagle bladze :|

0

ni błądzisz tylko że help i abstract sobie a kod sobie, tzn nie powinno działać ale działa :p

0
Misiekd napisał(a)

ni błądzisz tylko że help i abstract sobie a kod sobie, tzn nie powinno działać ale działa :p

to dopiero abstrakcja :-D

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