Le eccezioni sono un concetto OOP?

34

Dopo aver letto un post di ieri, mi sono reso conto che non sapevo molto sull'origine delle eccezioni. È solo un concetto correlato alla OOP? Tendo a pensare che lo sia, ma di nuovo ci sono eccezioni nel database.

    
posta John V 08.01.2013 - 08:38
fonte

8 risposte

2

Le eccezioni non sono un concetto di OOP.

Ma non sono completamente indipendenti neanche in un piccolo punto.

Come hanno mostrato altre risposte: Il concetto di eccezioni lo ha reso in diverse lingue non OOP. Nulla in questo concetto richiede qualcosa da OOP.

Ma qualsiasi se non tutti i linguaggi OOP che prendono seriamente OOP richiedono eccezioni perché gli altri metodi di gestione degli errori falliscono in un punto specifico: il costruttore.

Uno dei punti di OOP è che un oggetto deve incapsulare e gestire il suo stato interno in modo completo e coerente. Ciò significa anche che in puro OOP è necessario un concetto per creare un nuovo oggetto con uno stato conico "atomicamente" - tutto dall'allocazione della memoria (se necessario) all'inizializzazione a uno stato significativo (cioè semplice azzeramento la memoria non è sufficiente) deve essere eseguita in un'unica espressione. Quindi è richiesto un costruttore :

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

Ma ciò significa che anche il costruttore può fallire a causa di un errore. Come propagare le informazioni di errore dal costruttore senza eccezioni?

  • Valore restituito? Fallisce poiché in alcune lingue new potrebbe restituire solo null ma non tutte le informazioni significative. In altre lingue (ad es. C ++) myFoo non è un puntatore. Non è possibile controllarlo contro null . Inoltre non puoi chiedere myFoo sull'errore - non è inizializzato e quindi "non esiste" nel pensiero di OOP.

  • Flag di errore globale? Così tanto sullo stato di incapsulamento e poi su qualche variabile globale? Vai a h ...; -)

  • Una miscela? In nessun modo migliore.

Quindi le eccezioni sono un concetto più fondamentale di OOP, ma OOP si basa su di esse in modo naturale.

    
risposta data 08.01.2013 - 23:41
fonte
43

Is it OOP related only?

No. Eccezioni e OOP non sono correlati.

La gestione delle eccezioni è un meccanismo per gestire gli errori. Un'eccezione viene gestita salvando lo stato corrente di esecuzione in una posizione predefinita e passando l'esecuzione a una subroutine specifica nota come gestore di eccezioni.

Confronto tra C ( non proprio nella lingua OOP , possibile in qualche modo emulare eccezioni in C ) e C ++ (OOP, supporta eccezioni), nulla impedisce al comitato standard di C di aggiungere la gestione delle eccezioni a C, non funzionerà ancora in linguaggio C OOP.

    
risposta data 08.01.2013 - 09:03
fonte
12

Un'eccezione è, in poche parole, una situazione eccezionale che richiede attenzione e spesso un cambiamento nel flusso dell'esecuzione di un programma. Con questa definizione, le eccezioni e la gestione delle eccezioni non sono limitate all'orientamento agli oggetti e gli errori di programma semplici possono essere considerati una forma di eccezione.

Le lingue orientate agli oggetti di solito hanno una classe di eccezione nativa e, a seconda del contesto, la parola "eccezione" potrebbe effettivamente riferirsi a quella classe nativa invece che al concetto generale. La gestione delle eccezioni orientata agli oggetti è, come la maggior parte dell'orientamento agli oggetti, lo zucchero sintattico e può essere facilmente emulata in linguaggi decisamente non orientati agli oggetti. Ecco un esempio C, dal C Programming 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.");
    }
}
    
risposta data 08.01.2013 - 08:48
fonte
9

La risposta è un semplice NO.

Un buon esempio per un linguaggio non OO con eccezioni è ADA.

    
risposta data 08.01.2013 - 09:56
fonte
7

Alcune ottime risposte qui già. Altri esempi di linguaggi di programmazione non OOP con eccezioni:

  • Oracle PL / SQL

  • classico Visual Basic (V6 e sotto, "On Error Goto" è IMHO una forma di gestione delle eccezioni)

(Per essere nitty: trovi alcuni elementi OO in entrambi i linguaggi, ma i meccanismi di gestione delle eccezioni non li usano, suppongo perché il concetto è stato introdotto anni prima che gli elementi OO venissero aggiunti a quelle lingue).

    
risposta data 08.01.2013 - 10:09
fonte
5

L'idea alla base delle eccezioni è quella di ripulire il flusso del programma in modo che un programmatore possa seguire più facilmente il percorso di esecuzione "normale". Si consideri un semplice caso di apertura di un file in C. Subito dopo aver tentato di aprire il file, il programmatore deve esaminare la risposta dalla chiamata fopen () e decidere se la chiamata è riuscita. Se la chiamata non ha avuto successo, il programmatore deve rispondere in modo appropriato. La prossima chiamata nel percorso di esecuzione "normale", forse una chiamata a fread () o fwrite (), comparirà dopo che sono state gestite le condizioni di errore o di errore. Potrebbe essere nella schermata successiva.

Con una lingua che fornisce eccezioni, la chiamata fopen () equivalente può essere seguita immediatamente da fread () o fwrite (). Non esiste una gestione degli errori che nasconda il "prossimo passo" del percorso di esecuzione "normale". Il programmatore può vedere più del normale percorso su una singola schermata, e quindi può seguire l'esecuzione più facilmente. La gestione degli errori viene spostata in un'altra parte del programma.

Le eccezioni in sé non sono un concetto di OOP, ma sono spesso implementate usando concetti OOP che li rendono più convenienti e potenti. Ad esempio, le eccezioni possono essere definite con una gerarchia di ereditarietà. Usando il nostro esempio teorico di apertura, lettura o scrittura di un file, ognuna di queste chiamate può generare una serie di eccezioni: FileClosedException, DeviceFullException, NoSuchFileException, InsufficientFilePermissionsException, ecc. Ognuna di queste può ereditare da FileException, che può ereditare da IOException, che può ereditare da GenericException.

Se il programmatore sta eseguendo un'implementazione rapida e sporca per testare un concetto, potrebbe ignorare la gestione delle eccezioni e implementare semplicemente un singolo gestore per GenericException. Questo gestore gestirà una GenericException e qualsiasi eccezione che eredita da GenericException. Se vuole trattare qualsiasi eccezione relativa ai file allo stesso modo, può scrivere un gestore per FileException. Quello sarà chiamato per FileExceptions e qualsiasi eccezione che erediti da FileException. Se vuole scrivere un programma che risponderà in modo diverso a una varietà di condizioni di errore, può scrivere un gestore specifico per ogni specifica eccezione.

    
risposta data 08.01.2013 - 15:36
fonte
3

Altri hanno giustamente risposto "No" con esempi di lingue. Ho pensato che potrei estendere aggiungendo un esempio su come aggiungere eccezioni a una lingua senza coinvolgere mai OOP.

Lo farò nel caso del DSKL (Declarative Sequential Kernel Language) di OZ , un linguaggio adatto per il mondo accademico roba del genere. Il DSKL (o DKL) può essere visto qui (risultato di ricerca casuale ), la parte Dichiarazioni e valori. La definizione esatta non è importante, a parte il fatto che si tratta di un linguaggio molto semplice senza variabili modificabili (vengono dichiarati e successivamente associati) e senza OOP integrato.

OOP non può nemmeno essere aggiunto come astrazione linguistica a questo linguaggio del kernel. Aggiungendo nomi univoci al linguaggio del kernel (NewName) e utilizzando l'ambito locale, è possibile ottenere l'incapsulamento. O aggiungendo uno stato mutabile al linguaggio del kernel (NewCell) e utilizzando l'OOP appropriato con scope locale con incapsulamento può essere raggiunto. Ma non può essere ottenuto con il linguaggio del kernel specificato da solo.

Se aggiungiamo eccezioni al linguaggio del kernel avremo una lingua senza supporto OOP ma abbiamo delle eccezioni. Lasciami mostrare come:

Definendo una macchina astratta con una pila e una memoria, possiamo definire ciò che ogni affermazione nella nostra lingua dovrebbe fare (la semantica della dichiarazione). Ad esempio skip nello stack non dovrebbe fare nulla, A = 3 nello stack dovrebbe legare (/ unificare) A a (/ con) 3.

Iniziamo aggiungendo la sintassi di come devono essere definite le nostre eccezioni. Facciamo questo aggiungendo altre due clausole al <statement> nel DKL.

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

Ecco il try / catch conosciuto e un modo per aumentare / generare eccezioni.

Definiamo la loro semantica da come dovrebbero funzionare sulla macchina astratta:

Prova
L'istruzione semantica è: (try <statement1> catch <id> then <statement2> end)
Do:

  1. Spingi nello stack l'istruzione semantica (catch <id> then <statement2> end)
  2. Spingi nello stack l'istruzione semantica (<statement1>)

Nota che l'affermazione 1 sarà in cima allo stack, e provato prima.

Sollevare
L'istruzione semantica è: (raise <id> end)
Do:

  1. Se nulla di più è in pila, fermati e segnala un'eccezione non scoperta.
  2. Altrimenti, apri la prima dichiarazione semantica dallo stack. Se non è un'affermazione, vai al passaggio 1.
  3. Abbiamo ottenuto un fermo, nella forma (catch <id> then <statement> end)
    Spingi (<statement>) nello stack.

Cattura
Se vediamo una dichiarazione catch durante la normale esecuzione, ciò significa che qualsiasi cosa è stata eseguita all'interno senza elevare eccezioni fino a questo livello. Quindi inseriamo solo catch dello stack e non facciamo nulla.

QED, abbiamo una lingua con eccezioni e nessuna possibilità di OOP.

Ho rimosso la parte dell'ambiente dalla macchina astratta per renderla più semplice.

    
risposta data 08.01.2013 - 18:08
fonte
1

No.

IIRC, le eccezioni sono apparse prima delle prime lingue OO. AFAIK, le eccezioni sono state inizialmente supportate dalle prime implementazioni di LISP. I linguaggi strutturati in anticipo (ad esempio ALGOL) e le lingue OO precedenti (ad esempio SIMULA) non supportavano eccezioni.

    
risposta data 08.01.2013 - 21:24
fonte

Leggi altre domande sui tag