Sind Ausnahmen ein OOP-Konzept?

37

Nachdem ich gestern einen Beitrag gelesen hatte, wurde mir klar, dass ich nicht viel über die Entstehung von Ausnahmen wusste. Handelt es sich nur um ein OOP-Konzept? Ich glaube eher, dass dies der Fall ist, aber auch hier gibt es Datenbankausnahmen.

John V
quelle
Ich habe einmal gelesen, dass ein "Mr Goodenuf" (oder ähnliches) Ausnahmen erfunden hat, als Antwort auf "egal, es ist Goodenuf, wie!" Stil Mobbing. Ich kann momentan keine Referenz finden - vielleicht kann es jemand anderes. Es wäre interessant zu wissen, zu welcher Sprache sie zuerst hinzugefügt wurden.
Steve314
7
Haskell hat Ausnahmen und es ist überhaupt nicht OOP
jozefg
1
Obwohl Ausnahmen selbst nicht strikt objektorientiert sind, ist die übliche Praxis, Ausnahmen als Objekte zu definieren und Instanzen dieser Objekte zu werfen und zu fangen, eindeutig sehr ungenau.
Dougvj
Was ist der Unterschied zwischen einer Ausnahme und einem GOTO wäre eine interessante Frage.
Austin Henley
2
@Austin - wie wäre es mit ", obwohl Ausnahmewürfe das Prinzip eines einzigen Austrittspunkts verletzen, das einige der strengsten Anhänger der strukturierten Programmierung als absolut befürworten, erlauben sie keinen uneingeschränkten Spaghettikontrollfluss auf die Art und Weise, die dies gototut. Insbesondere das Ziel von Der Wurf wird durch den Kontext bestimmt, basierend auf der Verschachtelung von Blockstrukturen. Ausnahmen sind daher sogar von einer etwas weniger strengen Form der strukturierten Programmierung abhängig, bei der das Prinzip des einmaligen Ausstiegs als Richtlinie, aber nicht als absolute Regel verwendet wird. "
Steve314

Antworten:

5

Ausnahmen sind kein OOP-Konzept.

Aber sie haben auch in einem kleinen Punkt nichts miteinander zu tun.

Wie andere Antworten gezeigt haben: Das Konzept der Ausnahmen hat es in mehreren Nicht-OOP-Sprachen geschafft. Nichts in diesem Konzept erfordert etwas von OOP.

Aber alle, wenn nicht alle OOP-Sprachen, die OOP ernst nehmen, erfordern Ausnahmen, da die anderen Methoden zur Fehlerbehandlung an einer bestimmten Stelle fehlschlagen: dem Konstruktor.

Einer der Punkte von OOP ist, dass ein Objekt seinen internen Zustand vollständig und konsistent kapseln und verwalten soll. Dies bedeutet auch, dass Sie in pure OOP ein Konzept benötigen, um ein neues Objekt mit einem konsistenten Zustand "atomar" zu erstellen - alles was von der Speicherzuordnung (falls erforderlich) über die Initialisierung bis hin zu einem aussagekräftigen Zustand (dh einfaches Nullsetzen des Speichers ist nicht ausreichend) muss in einem Ausdruck erfolgen. Daher ist ein Konstruktor erforderlich:

Foo myFoo = Foo("foo", "bar", 42);

Dies bedeutet jedoch, dass der Konstruktor auch aufgrund eines Fehlers fehlschlagen kann. Wie werden die Fehlerinformationen ohne Ausnahmen aus dem Konstruktor ausgegeben?

  • Rückgabewert? Fehler, da in einigen Sprachen newnur nullaber keine aussagekräftigen Informationen zurückgegeben werden konnten. In anderen Sprachen (zB C ++) myFooist kein Zeiger. Man konnte es nicht überprüfen null. Sie können auch nicht myFoonach dem Fehler fragen - er ist nicht initialisiert und "existiert nicht" im OOP-Denken.

  • Globale Fehlerflagge? Soviel zum Einkapseln von Status und dann einer globalen Variablen? Geh zu h ... ;-)

  • Eine Mixtur? Auf keinen Fall besser.

  • ?

Ausnahmen sind also ein grundlegenderes Konzept als OOP, aber OOP baut auf natürliche Weise auf ihnen auf.

AH
quelle
3
Soweit ich das beurteilen kann, ist das einzige Wort in dieser "Antwort", das die tatsächlich gestellte Frage anspricht, "nicht". Der Rest scheint sich um Ausnahmen in OOP zu handeln - bei allem Respekt für mich liest sich dies irgendwo zwischen vage verwandt und völlig irrelevant - wieder im Kontext der gestellten Frage
gnat
@gnat: Der TO sagt auch, dass er nicht über die Ursprünge von Ausnahmen Bescheid weiß. Daher schien ein kleiner Hintergrund, warum Ausnahmen überall in OO-Land sind, für mich in Ordnung zu sein. YMMV
AH
1
@AH Ich muss Mücke zustimmen, abgesehen von der Eröffnungszeile, es geht wirklich nicht um die Frage. Ihre Antwort auf gnat lautete "sagt, er weiß nicht, woher die Ausnahmen stammen", aber Sie gaben tatsächlich keinen Ursprung für Ausnahmen an, sondern nur eine zufällige Verwendung von Ausnahmen während der Objektinstanziierung.
Jungs, im Ernst? -1? Die meisten anderen Antworten sind auch nicht 100% zutreffend. +1 von mir zu kompensieren. Diese Antwort gibt gute Hintergrundinformationen in einer Welt mit kaputten Klassenentwürfen. (Änderung: Erwähnen Sie mehrstufige Konstruktoren sollten vermieden werden)
Jo So
44

Geht es nur um OOP?

Nein. Ausnahmen und OOP haben nichts zu tun.

Die Behandlung von Ausnahmen ist ein Mechanismus zur Behandlung von Fehlern. Eine Ausnahme wird behandelt, indem der aktuelle Ausführungsstatus an einem vordefinierten Ort gespeichert und die Ausführung auf ein bestimmtes Unterprogramm umgeschaltet wird, das als Ausnahmebehandlungsroutine bezeichnet wird.

Vergleicht man C ( nicht wirklich OOP-Sprache , es ist möglich, Ausnahmen in C zu emulieren ) und C ++ (OOP, unterstützt Ausnahmen), so hindert nichts das Standardkomitee von C daran, C Ausnahmen zuzuweisen, und macht C trotzdem nicht zu einer OOP-Sprache.

BЈовић
quelle
2
Man könnte sogar behaupten, dass im normalen Betriebssystem bereits einige Ausnahmen unterstützt werden. Lassen Sie Ihr Programm abstürzen (die unberührte "Ausnahme") und mit einem Core-Dump und einem Debugger erhalten Sie sogar einen Stack-Trace.
Bhaak
12
Sogar MS BASIC aus den frühen ON ERROR GOTO xxxx
80ern
1
@bhaak Er könnte auch über Speicherabbilder in Windows sprechen
JohnL
11
@jwernerny Fehlerbehandlung? Sicher. Aber niemand würde diese Ausnahmebehandlung nennen. In der Tat war es routinemäßig im Gegensatz zu (strukturierter) Ausnahmebehandlung.
Konrad Rudolph
1
@jwernerny nicht sicher, ob ich folge; Ausnahmebehandlung, wie ich verstanden habe, ist eine sehr spezielle Methode zur Fehlerbehandlung. Wenn ich Ausnahmen höre, denke ich immer an das try catchKonstrukt.
Andy
12

Eine Ausnahme ist, einfach ausgedrückt, eine Ausnahmesituation, die Aufmerksamkeit erfordert und häufig eine Änderung des Programmablaufs zur Folge hat. Nach dieser Definition sind Ausnahmen und die Behandlung von Ausnahmen nicht auf die Objektorientierung beschränkt, und einfache Programmfehler können als eine Form der Ausnahme angesehen werden.

Objektorientierte Sprachen haben normalerweise eine native Ausnahmeklasse, und abhängig vom Kontext kann sich das Wort "Ausnahme" in der Tat auf diese native Klasse beziehen, anstatt auf das allgemeine Konzept. Die objektorientierte Ausnahmebehandlung ist, wie der Großteil der Objektorientierung, syntaktischer Zucker und kann leicht in eindeutig nicht objektorientierten Sprachen emuliert werden. Hier ist ein C-Beispiel aus dem C-Programmier-Wikibook :

#include <stdio.h>
#include <setjmp.h>

jmp_buf test1;

void tryjump()
{
    longjmp(test1, 3);
}

int main (void)
{
    if (setjmp(test1)==0) {
        printf ("setjmp() returned 0.");
        tryjump();
    } else {
        printf ("setjmp returned from a longjmp function call.");
    }
}
yannis
quelle
6
Es ist nicht nur syntaktischer Zucker. Mit setjmp ist es schwierig, einen vollständigen Stack-Abwickler und typbasierte Catch-Handler wiederherzustellen. Die spezielle Zusammenstellung von Ausnahmen führt außerdem zu Vorteilen, die von setjmp nicht nachgeahmt werden können.
edA-qa mort-ora-y
3
Ich hasse die Beschreibung Ausnahmen sind Ausnahmesituationen. Ich würde eher sagen, dass Ausnahmen generiert (ausgelöst) werden sollten, wenn eine Fehlersituation mit dem aktuellen Kontext nicht behoben werden kann, da im aktuellen Kontext nicht genügend Informationen vorhanden sind, um den Fehler korrekt zu beheben.
Martin York
+1 für setjmp.h
gnat
9

Die Antwort ist ein einfaches NEIN.

Ein gutes Beispiel für eine Nicht-OO-Sprache mit Ausnahmen ist ADA.

Uwe Plonus
quelle
4
Hm, warum ist ADA keine OO-Sprache? Zugegeben, ADA83 wies keinen Polymorphismus auf, konnte aber dennoch als objektbasiert angesehen werden. Auch seit ADA95 ist die Sprache vollständig objektorientiert.
Yannis
Soweit ich weiß, ist die Ausnahmebehandlung älter als ADA83, daher ist ADA an sich eine Nicht-OO mit Ausnahmebehandlung.
Uwe Plonus
2
@ YannisRizos: Ada83 hat Pakete und generische Pakete, aber keine Objekte. Sie wurden mit Ada95 eingeführt.
Mouviciel
2
@Yannis - Objekte ohne Polymorphismus sind wie strukturierte Programmierung ohne verschachtelte Blöcke. Polymorphismus ist eines der bestimmenden Merkmale von OOP. Selbst in Ada95 werden die Typen, die die Laufzeitbindung unterstützen, als "markierte Typen" und nicht als "Klassen" bezeichnet, obwohl dies natürlich nur Rechtschreibung ist. Ada 83 hatte Variantendatensätze und verschiedene andere Typen, aber keiner dieser Typen bietet OOP-spezifische Funktionen. Ada 83 war modular und strukturiert, aber nicht objektorientiert.
Steve314
3
@Yannis - im Grunde können einige Leute in der Ada-Community (wie einige Befürworter der meisten Sprachen) nicht akzeptieren, dass ein Feature gut sein kann, aber nicht in ihrer Lieblingssprache implementiert ist, und werden alle möglichen Gründe dafür finden, etwas anderes zu glauben. Es ist jedoch nicht einmal so, als ob eine gute Sprache alle möglichen guten Sprachfunktionen haben muss (obwohl es leicht zu glauben ist, dass die Ada-Designer dies dachten). Ich glaube nicht wirklich an den minimalistischen Ansatz des Sprachdesigns, aber auch maximalistische Sprachen sind nicht perfekt.
Steve314
7

Einige sehr gute Antworten hier schon. Andere Beispiele für Nicht-OOP-Programmiersprachen mit Ausnahmen:

  • Oracle PL / SQL

  • klassisches Visual Basic (ab V6 ist "On Error Goto" IMHO eine Form der Ausnahmebehandlung)

(Um ehrlich zu sein: Sie finden einige OO-Elemente in beiden Sprachen, aber die Ausnahmebehandlungsmechanik nutzt sie nicht, ich denke, weil das Konzept Jahre vor dem Hinzufügen der OO-Elemente zu diesen Sprachen eingeführt wurde.)

Doc Brown
quelle
Zumindest die späteren QuickBASIC-Versionen unter DOS (die vor Visual Basic lagen; QB 4.5 war 1988 laut Wikipedia, VB 1.0 1991) hatten eine Fehlerbehandlung unter Verwendung der ON ERROR GOTOSyntax. Sogar QuickBASIC hatte ein paar OO-ähnliche Konzepte (ich glaube, QB 4.5 unterstützte sogar Klassen), aber es würde Ihnen schwer fallen, das meist traditionelle BASIC als eine richtige objektorientierte Sprache zu bezeichnen. [Wikipedia ]
ein Lebenslauf vom
5

Die Grundidee hinter Ausnahmen besteht darin, den Programmfluss zu bereinigen, damit ein Programmierer dem "normalen" Ausführungspfad leichter folgen kann. Stellen Sie sich einen einfachen Fall vor, in dem eine Datei in C geöffnet wird. Unmittelbar nach dem Versuch, die Datei zu öffnen, muss der Programmierer die Antwort des Aufrufs von fopen () untersuchen und entscheiden, ob der Aufruf erfolgreich war. Wenn der Aufruf nicht erfolgreich war, muss der Programmierer entsprechend reagieren. Der nächste Aufruf im "normalen" Ausführungspfad, möglicherweise ein Aufruf von fread () oder fwrite (), würde erscheinen, nachdem die Fehler- oder Fehlerbedingungen behandelt wurden. Das kann auf dem nächsten Bildschirm sein.

Mit einer Sprache, die Ausnahmen bereitstellt, kann dem entsprechenden Aufruf von fopen () sofort das Wort fread () oder fwrite () folgen. Es gibt keine Fehlerbehandlung, die den "nächsten Schritt" des "normalen" Ausführungspfads verbirgt. Der Programmierer kann mehr vom normalen Pfad auf einem einzigen Bildschirm sehen und so die Ausführung leichter verfolgen. Die Fehlerbehandlung wird in einen anderen Programmteil verschoben.

Ausnahmen selbst sind kein OOP-Konzept, werden jedoch häufig mithilfe von OOP-Konzepten implementiert, die sie komfortabler und leistungsfähiger machen. Beispielsweise können Ausnahmen mit einer Vererbungshierarchie definiert werden. Anhand unseres Beispiels zum Öffnen und Lesen oder Schreiben einer Datei können bei jedem dieser Aufrufe verschiedene Ausnahmen auftreten - FileClosedException, DeviceFullException, NoSuchFileException, InsquateFilePermissionsException usw. Jede dieser Ausnahmen kann von FileException erben, die möglicherweise von IOException erben von GenericException erben.

Wenn der Programmierer eine schnelle und fehlerhafte Implementierung ausführt, um ein Konzept zu testen, ignoriert er möglicherweise meistens die Ausnahmebehandlung und implementiert nur einen einzelnen Handler für GenericException. Dieser Handler behandelt eine GenericException und alle Ausnahmen, die von GenericException erben. Wenn er dateibezogene Ausnahmen gleich behandeln möchte, kann er einen Handler für FileException schreiben. Das wird für FileExceptions und alle Ausnahmen aufgerufen, die von FileException erben. Wenn er ein Programm schreiben möchte, das auf eine Vielzahl von Fehlerbedingungen unterschiedlich reagiert, kann er für jede bestimmte Ausnahme einen bestimmten Handler schreiben.

MikeD
quelle
3

Andere haben zu Recht mit Sprachbeispielen mit "Nein" geantwortet. Ich dachte, ich könnte erweitern, indem ich ein Beispiel hinzufüge, wie man einer Sprache Ausnahmen hinzufügt, ohne jemals OOP zu involvieren.

Ich werde dies im Falle der DSKL (Declarative Sequential Kernel Language) von OZ tun , einer Sprache, die für solche akademischen Dinge gut geeignet ist. Die DSKL (oder DKL) zu sehen hier (Zufallssucher), die Aussagen und Werte Teil. Die genaue Definition ist nicht wichtig, außer dass dies eine sehr einfache Sprache ist, in der keine veränderbaren Variablen (sie werden deklariert und später gebunden) und keine OOP eingebaut sind.

OOP kann nicht einmal als sprachliche Abstraktion zu dieser Kernelsprache hinzugefügt werden. Durch Hinzufügen eindeutiger Namen zur Kernelsprache (NewName) und Verwendung des lokalen Gültigkeitsbereichs kann die Kapselung erreicht werden. Oder durch Hinzufügen eines veränderlichen Status zur Kernelsprache (NewCell) und Verwendung des lokalen Gültigkeitsbereichs kann eine ordnungsgemäße OOP mit Kapselung erreicht werden. Mit der angegebenen Kernelsprache allein ist dies jedoch nicht möglich.

Wenn wir dann der Kernelsprache Ausnahmen hinzufügen, haben wir eine Sprache ohne OOP-Unterstützung, aber mit Ausnahmen. Lassen Sie mich zeigen, wie:

Indem wir eine abstrakte Maschine mit einem Stapel und einem Speicher definieren, können wir definieren, was jede Anweisung in unserer Sprache tun soll (die Semantik der Anweisung). Zum Beispiel skipim Stapel sollte nichts tun, A = 3im Stapel sollte (/ vereinheitlichen) A an (/ mit) 3 binden.

Wir beginnen mit dem Hinzufügen der Syntax, wie unsere Ausnahmen definiert werden sollen. Dazu fügen wir <statement>der DKL zwei weitere Klauseln hinzu .

<statement>  ::== ... (old stuff)
                 | try <statement> catch <id> then <statement> end
                 | raise <id> end

Hier ist der bekannte Versuch / Fang und eine Möglichkeit, Ausnahmen auszulösen / zu werfen.

Wir definieren ihre Semantik, wie sie auf der abstrakten Maschine arbeiten sollen:

Try
Die semantische Aussage lautet: (try <statement1> catch <id> then <statement2> end)
Do:

  1. Schieben Sie die semantische Anweisung auf den Stapel (catch <id> then <statement2> end)
  2. Schieben Sie die semantische Anweisung auf den Stapel (<statement1>)

Beachten Sie, dass Anweisung 1 oben auf dem Stapel abgelegt und zuerst ausgeführt wird.

Raise
Die semantische Aussage lautet: (raise <id> end)
Do:

  1. Wenn sich nichts mehr auf dem Stapel befindet, halten Sie an und melden Sie eine nicht erfasste Ausnahme.
  2. Andernfalls können Sie die erste semantische Anweisung vom Stapel nehmen. Wenn es sich nicht um eine catch-Anweisung handelt, fahren Sie mit Schritt 1 fort.
  3. Wir haben einen Haken bekommen, auf dem Formular (catch <id> then <statement> end)
    Schieben Sie (<statement>)auf den Stapel.

Catch
Wenn während der normalen Ausführung eine catch-Anweisung angezeigt wird, bedeutet dies, dass alles, was in der Ausführung enthalten war, ohne Ausnahmen bis zu dieser Stufe ausgeführt wurde. Also werfen wir einfach catchden Stack ab und machen nichts.

QED, wir haben eine Sprache mit Ausnahmen und keine Möglichkeit von OOP.

Ich habe den Umgebungsteil von der abstrakten Maschine entfernt, um es einfacher zu machen.

Matsemann
quelle
1

Nein.

IIRC, Ausnahmen erschienen vor den ersten OO-Sprachen. AFAIK, Ausnahmen wurden zuerst durch frühe LISP-Implementierungen unterstützt. Frühe strukturierte Sprachen (zB ALGOL) und frühe OO-Sprachen (zB SIMULA) unterstützten keine Ausnahmen.

Kevin Cline
quelle
ALGON 68 hatte natürlich Ausnahmen ("Ereignisse"), aber es hatte auch alles andere. PL / I hatte sie auch ("Einschaltbedingungen"), und es gibt Literatur von 1969, die ihre Verwendung beschreibt.
Ross Patterson