Warum kann ich eine abstrakte Klasse instantiieren?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Marsmännchen
Beiträge: 294
Registriert: So 4. Mai 2014, 21:32
OS, Lazarus, FPC: Ubuntu 16.04, FPC 3.0.2, Lazarus 1.6.4
CPU-Target: 64bit
Wohnort: Berlin

Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von Marsmännchen »

Hi,

ich bastel mir gerade eine Klasse. Diese soll abstrakt sein, was nach meinem Verständnis bedeutet, dass ich von ihr keine Objekte erstellen kann. Sie soll als Basisklasse für konkretere Klassen dienen:

Code: Alles auswählen

 {TBuchung: Abstrakte Klasse, von der später die anderen Buchungsklassen
   erben und die für die Collection verwendet wird, welche die Buchungen dann
   hält}

      EBuchungsart = (baEinnahme, baAusgabe);
      EZahlungsart = (zaAbbuchung, zaUeberweisung, zaDauerauftrag, zaBar,
                      zaAbhebung);
      EZahlungsperiode = (zpMonat, zpZweiMonate, zpQuartal, zpHalbjahr, zpJahr);
   TBuchung = class
     public
       procedure dummyProc; virtual; abstract;
     protected
       FName : String; // Bezeichnung der Buchung
       FBuchungsart : EBuchungsart;
       FKategorie : String; // Kategorie ist Sortieroption für Buchungen
       FZahlungsart : EZahlungsart;
       FZahlungsperiode : EZahlungsperiode;
       FBemerkungen : String;
 
   end;                                   


Die Dummy-Methode habe ich auch nur eingesetzt, weil ich nicht weiß, wie ich sonst die Klasse abstrakt machen soll, abstract kann ja nur auf Methoden und nicht auf Klassen angewendet werden. Das Blöde in meinem Fall ist, dass die Klasse ein reiner Datencontainer (so eine Art Pojo) sein soll und die Methode ansonsten überflüssig ist.

Wie dem auch sei: Komischerweise kann ich von meiner abstrakten Klasse Objekte erstellen. Ich kriege lediglich eine Compilerwarnung.
mfk3test.pas(44,31) Warning: Constructing a class "TBuchung" with abstract method "dummyProc"

Und das ist alles. Was mache ich falsch? Habe jetzt eine Weile im Internet gestöbert, aber keine Lösungen gefunden.
Ich mag Pascal...

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 4187
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von af0815 »

Willst du nicht eher ein Interface definieren ?

Siehe http://wiki.freepascal.org/How_To_Use_Interfaces

Andreas
Zuletzt geändert von af0815 am Fr 4. Aug 2017, 11:59, insgesamt 1-mal geändert.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 8339
Registriert: Mo 11. Sep 2006, 19:01

Re: Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von theo »


wp_xyz
Beiträge: 3271
Registriert: Fr 8. Apr 2011, 09:01

Re: Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von wp_xyz »

Gibt es "abstrakte Klassen" überhaupt in Object Pascal? "Abstrakte Methoden", ja, und die verwendest du. Man kann von einer Klasse, die abstrakte Methoden verwendet, durchaus Instanzen erzeugen, nur kann man die abstrakten Methoden nicht aufrufen (--> Exception). Sie sind Platzhalter, die von abgeleiteten Klassen überschrieben werden müssen

Marsmännchen
Beiträge: 294
Registriert: So 4. Mai 2014, 21:32
OS, Lazarus, FPC: Ubuntu 16.04, FPC 3.0.2, Lazarus 1.6.4
CPU-Target: 64bit
Wohnort: Berlin

Re: Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von Marsmännchen »

af0815 hat geschrieben:Willst du nicht eher ein Interface definieren ?

Siehe http://wiki.freepascal.org/How_To_Use_Interfaces

Andreas
Hatte ich auch schon dran gedacht (den Link kenne ich auch, aber ich habe das Prog noch nicht ganz verstanden... muss es mal im Debugger durchgehen).
Das Problem mit Interfaces ist hier, dass ich ja ein fast reines Datenobjekt haben will und Interfaces kennen keine Felder... wie also die Daten abbilden?
Jetzt hab ich nochmal in der Doku gestöbert und Interfaces kennen Propertys. Die könnte ich natürlich in den realen Klassen mit Feldern und/oder Methoden hinterlegen. Meintest du sowas?

Edit: Ich habe jetzt mal folgendes gebastelt, muss es aber noch ausprobieren:

Code: Alles auswählen

IBuchungBasis = interface
     property Name : String;
     property Buchungsart : EBuchungsart;
     property Kategorie : String;
     property Zahlungsart : EZahlungsart;
     property Zahlungsperiode : EZahlungsperiode;
     property Bemerkungen : String;
   end;     
Zuletzt geändert von Marsmännchen am Fr 4. Aug 2017, 15:34, insgesamt 1-mal geändert.
Ich mag Pascal...

Marsmännchen
Beiträge: 294
Registriert: So 4. Mai 2014, 21:32
OS, Lazarus, FPC: Ubuntu 16.04, FPC 3.0.2, Lazarus 1.6.4
CPU-Target: 64bit
Wohnort: Berlin

Re: Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von Marsmännchen »

theo hat geschrieben:Kurze Antwort: Isso. :wink:

http://forum.lazarus-ide.org/index.php?topic=17547.0


Kurz und knackig :lol: Aber okay, dann weiß ich das und frickel nicht mehr weiter um dem Ding neue Kunststücke beizubringen. Bei meinen kleinen Projekten kann ich mir auch noch größtenteils merken, welche Klassen für mich unantastbar sein sollen.
Ich mag Pascal...

Marsmännchen
Beiträge: 294
Registriert: So 4. Mai 2014, 21:32
OS, Lazarus, FPC: Ubuntu 16.04, FPC 3.0.2, Lazarus 1.6.4
CPU-Target: 64bit
Wohnort: Berlin

Re: Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von Marsmännchen »

wp_xyz hat geschrieben:Gibt es "abstrakte Klassen" überhaupt in Object Pascal? "Abstrakte Methoden", ja, und die verwendest du. Man kann von einer Klasse, die abstrakte Methoden verwendet, durchaus Instanzen erzeugen, nur kann man die abstrakten Methoden nicht aufrufen (--> Exception). Sie sind Platzhalter, die von abgeleiteten Klassen überschrieben werden müssen

Na ich habe wohl die Denke von Java/C# hier auf Object Pascal angewendet. Nun weiß ich es ab sofort (hoffentlich) besser 8)
Ich mag Pascal...

braunbär
Beiträge: 294
Registriert: Do 8. Jun 2017, 18:21

Re: Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von braunbär »

Meines Erachtens ist das ein Manko von Free Pascal.
Stecken da irgend welche Überlegungen dahinter, oder wurden abstrakte Klassen bei der Sprachdefinition einfach "vergessen"?
In Delphi gibt es abstrakte Klassen und die können schon seit ziemlich langer Zeit nicht instanziert werden, nur in den ersten Versionen von Delphi, in denen diese Deklaration möglich war, hat man vergessen, das Erzeugen von Instanzen abstrakter Klassen zu verbieten.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 4187
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von af0815 »

Code: Alles auswählen

type
  EBuchungsart = (baEinnahme, baAusgabe);
  EZahlungsart = (zaAbbuchung, zaUeberweisung, zaDauerauftrag, zaBar,
                zaAbhebung);
  EZahlungsperiode = (zpMonat, zpZweiMonate, zpQuartal, zpHalbjahr, zpJahr);
 
  TBuchung = class
  private
    function GetBemerkungen: String;virtual; abstract;
    function GetBuchungsart: EBuchungsart;virtual; abstract;
    function GetKategorie: String;virtual; abstract;
    function GetName: String;virtual; abstract;
    function GetZahlungsart: EZahlungsart;virtual; abstract;
    function GetZahlungsperiode: EZahlungsperiode;virtual; abstract;
    procedure SetBemerkungen(AValue: String);virtual; abstract;
    procedure SetBuchungsart(AValue: EBuchungsart);virtual; abstract;
    procedure SetKategorie(AValue: String);virtual; abstract;
    procedure SetName(AValue: String);virtual; abstract;
    procedure SetZahlungsart(AValue: EZahlungsart);virtual; abstract;
    procedure SetZahlungsperiode(AValue: EZahlungsperiode);virtual; abstract;
  protected
    property Name : String read GetName write SetName; // Bezeichnung der Buchung
    property Buchungsart : EBuchungsart read GetBuchungsart write SetBuchungsart;
    property Kategorie : String read GetKategorie write SetKategorie; // Kategorie ist Sortieroption für Buchungen
    property Zahlungsart : EZahlungsart read GetZahlungsart write SetZahlungsart;
    property Zahlungsperiode : EZahlungsperiode read GetZahlungsperiode write SetZahlungsperiode;
    property Bemerkungen : String read GetBemerkungen write SetBemerkungen;
  end;
 

Sowas in der Art ?

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Socke
Lazarusforum e. V.
Beiträge: 2750
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von Socke »

braunbär hat geschrieben:Meines Erachtens ist das ein Manko von Free Pascal.
Stecken da irgend welche Überlegungen dahinter, oder wurden abstrakte Klassen bei der Sprachdefinition einfach "vergessen"?
In Delphi gibt es abstrakte Klassen und die können schon seit ziemlich langer Zeit nicht instanziert werden, nur in den ersten Versionen von Delphi, in denen diese Deklaration möglich war, hat man vergessen, das Erzeugen von Instanzen abstrakter Klassen zu verbieten.

In Delphi kann man auch abstrakte Klassen instanziieren, auch wenn es nicht mehr empfohlen ist. Warum man es verbieten muss, wenn man eine Warnung erhält, erschließt sich mir aber nicht.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Marsmännchen
Beiträge: 294
Registriert: So 4. Mai 2014, 21:32
OS, Lazarus, FPC: Ubuntu 16.04, FPC 3.0.2, Lazarus 1.6.4
CPU-Target: 64bit
Wohnort: Berlin

Re: Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von Marsmännchen »

af0815 hat geschrieben:
Sowas in der Art ?

Andreas


Na klar :shock: . So geht das auch! Auf die Idee bin ich garnicht gekommen. Ich war wohl zu fixiert auf eine reine Daten-Klasse.

Jetzt führen plötzlich mehrere Wege zu meiner Basisklasse... momentan neige ich dazu, es erstmal mit einem Interface zu probieren. Ich finde die Idee witzig 8) .
Ich mag Pascal...

Marsmännchen
Beiträge: 294
Registriert: So 4. Mai 2014, 21:32
OS, Lazarus, FPC: Ubuntu 16.04, FPC 3.0.2, Lazarus 1.6.4
CPU-Target: 64bit
Wohnort: Berlin

Re: Warum kann ich eine abstrakte Klasse instantiieren?

Beitrag von Marsmännchen »

Socke hat geschrieben:...In Delphi kann man auch abstrakte Klassen instanziieren,[/url] auch wenn es nicht mehr empfohlen ist. Warum man es verbieten muss, wenn man eine Warnung erhält, erschließt sich mir aber nicht.


Naja, das muss man sicher nicht, aber wenn man sich andere Sprachen ansieht, dann ist dass dort halt so und man erwartet es erstmal bei Pascal auch. Ich habe jetzt durch die Diskussion hier und das Beschäftigen mit dem Thema den Eindruck gewonnen, dass ObjectPascal mit diesen Kapselungsmechanismen halt etwas anders umgeht, wie C++ und Nachfolger (z.B. auch, dass private-Sachen in der ganzen Unit sichtbar sind). Kapselung wird etwas anders betrachtet, fast ein bisschen wie bei Python (wer hat da wohl von wem gespickt :wink: ). Etwas mehr lazy im Gegensatz zur Typsicherheit... oder?
Ich mag Pascal...

Antworten