¿Son las excepciones un concepto OOP?

37

Después de leer una publicación ayer, me di cuenta de que no sabía mucho sobre el origen de las excepciones. ¿Es solo un concepto relacionado con OOP? Tiendo a pensar que sí, pero de nuevo hay excepciones en la base de datos.

Juan v
fuente
Una vez leí que un "Sr. Goodenuf" (o similar) inventó excepciones en respuesta a "no importa, es Goodenuf, ¡eh!" estilo bullying. Parece que no puedo encontrar una referencia ahora, tal vez alguien más pueda. Sería interesante saber a qué idioma se agregaron primero.
Steve314
77
Haskell tiene excepciones y no es POO en absoluto
Daniel Gratzer
1
Aunque las excepciones en sí mismas no están estrictamente orientadas a objetos, la práctica común de definir excepciones como objetos y lanzar y atrapar instancias de estos objetos claramente es muy POO.
Dougvj
¿Cuál es la diferencia entre una excepción y un GOTO? Sería una pregunta interesante.
Austin Henley
2
@Austin: ¿qué tal "aunque los lanzamientos de excepciones violan el principio del punto de salida único de que algunos de los discípulos más estrictos de la programación estructurada abogan como un absoluto, no permiten el flujo de control de espaguetis sin restricciones de la manera que lo gotohace. En particular, el objetivo de el lanzamiento está determinado por el contexto, basado en el anidamiento de estructuras de bloques. Como tal, las excepciones incluso dependen de una forma ligeramente menos estricta de programación estructurada donde el principio de salida única se toma como una guía, pero no como un absoluto ".
Steve314

Respuestas:

5

Las excepciones no son un concepto OOP.

Pero tampoco están completamente ajenos en un pequeño punto.

Como han mostrado otras respuestas: el concepto de excepciones lo ha hecho en varios idiomas que no son OOP. Nada en ese concepto requiere algo de OOP.

Pero cualquiera, si no todos los lenguajes OOP que toman en serio OOP requieren excepciones porque los otros métodos de manejo de errores fallan en un punto específico: el constructor.

Uno de los puntos de OOP es que un objeto debe encapsular y administrar su estado interno de manera completa y consistente. Esto también significa que en OOP puro necesita un concepto para crear un nuevo objeto con un estado coherente "atómicamente": todo, desde la asignación de memoria (si es necesario) hasta la inicialización a un estado significativo (es decir, la puesta a cero simple de la memoria no es suficiente) hacerse en una sola expresión. Por lo tanto, se requiere un constructor :

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

Pero esto significa que el constructor también puede fallar debido a algún error. ¿Cómo propagar la información del error desde el constructor sin excepciones?

  • Valor de retorno? Falla ya que en algunos idiomas newsolo puede devolver nullinformación significativa, pero no ninguna. En otros lenguajes (por ejemplo, C ++) myFoono es un puntero. No se pudo comprobarlo null. Además, no puede preguntar myFoosobre el error: no está inicializado y, por lo tanto, "no existe" en el pensamiento OOP.

  • ¿Indicador de error global? ¿Tanto sobre el estado de encapsulación y luego alguna variable global? Ve a h ... ;-)

  • ¿Una mezcla? De ninguna manera mejor.

  • ?

Por lo tanto, las excepciones son un concepto más fundamental que OOP, pero OOP se basa en ellas de forma natural.

AH
fuente
3
Por lo que puedo decir, la única palabra en esta "respuesta" que aborda la pregunta real es "no". El resto parece ser sobre excepciones en OOP, con todo el debido respeto para mí, esto se lee en algún lugar entre vagamente relacionado y totalmente irrelevante , nuevamente, en el contexto de la pregunta formulada
mosquito el
@gnat: El TO también dice que no conoce los orígenes de las excepciones. Por lo tanto, un poco de información sobre por qué las excepciones están en todas partes en tierra de OO parecía estar bien para mí. YMMV
AH
1
@AH Tengo que estar de acuerdo con el mosquito, aparte de la línea de apertura, realmente no responde a la pregunta. Su respuesta al mosquito fue "dice que no conoce los orígenes de las excepciones", pero en realidad no proporcionó un origen de excepciones, solo un uso aleatorio de excepciones durante la creación de instancias de objetos.
Chicos, en serio? -1? La mayoría de las otras respuestas tampoco son 100% precisas. +1 de mi parte para compensar. Esta respuesta da buenos consejos de fondo en un mundo de diseños de clase rotos. (Enmienda: Mencione los constructores de varios pasos que deben evitarse)
Jo So
44

¿Está relacionado solo con POO?

No. Las excepciones y la POO no están relacionadas.

El manejo de excepciones es un mecanismo para manejar errores. Una excepción se maneja guardando el estado actual de ejecución en un lugar predefinido y cambiando la ejecución a una subrutina específica conocida como controlador de excepciones.

Comparando C ( no realmente el lenguaje OOP , es posible emular excepciones de alguna manera en C ) y C ++ (OOP, admite excepciones), nada impide que el comité estándar de C agregue el manejo de excepciones a C, todavía no hará que C sea un lenguaje OOP.

BЈовић
fuente
2
Incluso podría argumentar que ya hay algún tipo de excepciones admitidas en el sistema operativo habitual. Deje que su programa se bloquee (la "excepción" no detectada) y con un volcado de núcleo y un depurador, incluso obtendrá un seguimiento de la pila.
bhaak
12
Incluso MS BASIC desde principios de los 80 tuvo un manejo de excepciones:ON ERROR GOTO xxxx
jwernerny
1
@bhaak También podría estar hablando de volcados de memoria en Windows
JohnL
11
@jwernerny ¿Manejo de errores? Seguro. Pero nadie llamaría a eso manejo de excepciones. De hecho, se contrastaba habitualmente con el manejo de excepciones (estructuradas).
Konrad Rudolph
1
@jwernerny no estoy seguro de seguir; manejo de excepciones, como he entendido, es una forma muy específica de manejar errores. Cuando escucho excepciones, siempre pienso en el try catchconstructo.
Andy
12

Una excepción es, simplemente, una situación excepcional que requiere atención y, a menudo, un cambio en el flujo de la ejecución de un programa. Según esa definición, las excepciones y el manejo de excepciones no se limitan a la orientación a objetos, y los errores simples del programa pueden considerarse una forma de excepción.

Los lenguajes orientados a objetos suelen tener una clase de excepción nativa y, según el contexto, la palabra "excepción" podría referirse a esa clase nativa en lugar del concepto general. El manejo de excepciones orientado a objetos es, como la mayoría de la orientación a objetos, azúcar sintáctica, y puede emularse fácilmente en lenguajes decididamente no orientados a objetos. Aquí hay un ejemplo de C, del wikibook de Programación en C :

#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
fuente
66
No es simplemente azúcar sintáctico. Recreando una pila completa de desenrollado y controladores de captura basados ​​en tipos es difícil con setjmp. Además, la compilación especial de excepciones da como resultado ventajas que setjmp no puede imitar.
edA-qa mort-ora-y
3
Odio la descripción, las excepciones son situaciones excepcionales. Prefiero decir que se deben generar (lanzar) excepciones cuando una situación de error no se puede resolver con el contexto actual porque no hay suficiente información en el contexto actual para corregir correctamente el error.
Martin York
+1 para setjmp.h
mosquito
9

La respuesta es un simple NO.

Un buen ejemplo para un lenguaje no OO con excepciones es ADA.

Uwe Plonus
fuente
44
Hm, ¿por qué ADA no es un lenguaje OO? Por supuesto, ADA83 carecía de polimorfismo, pero aún podría considerarse basado en objetos. Además, desde ADA95, el lenguaje está totalmente orientado a objetos.
Yannis
Hasta donde sé, el manejo de excepciones es más antiguo que ADA83, por lo tanto, ADA en sí mismo es un no-OO con manejo de excepciones.
Uwe Plonus
2
@YannisRizos: Ada83 tiene paquetes y paquetes genéricos pero no objetos. Fueron presentados con Ada95.
Mouviciel
2
@ Yannis: los objetos sin polimorfismo son como una programación estructurada sin bloques anidados. El polimorfismo es uno de los rasgos definitorios de la POO. Incluso en Ada95, los tipos que admiten el enlace en tiempo de ejecución se denominan "tipos etiquetados" en lugar de "clases", aunque, por supuesto, eso es solo ortografía. Ada 83 tenía registros de variantes y varios otros tipos, pero ninguno de esos tipos proporciona características que son específicas de OOP. Ada 83 era modular y estructurado, pero no estaba orientado a objetos.
Steve314
3
@Yannis: básicamente, algunas personas en la comunidad Ada (como algunos defensores de la mayoría de los idiomas) no pueden aceptar que una característica puede ser buena, pero no implementada en su idioma favorito, y crearán todo tipo de excusas para creer lo contrario. Sin embargo, ni siquiera es como si un buen lenguaje necesita tener todas las características posibles de un buen lenguaje (aunque es fácil creer que los diseñadores de Ada pensaron que sí). Realmente no creo en el enfoque minimalista del diseño del lenguaje, pero los lenguajes maximalistas tampoco son perfectos.
Steve314
7

Algunas muy buenas respuestas aquí ya. Otros ejemplos para lenguajes de programación que no son OOP que tienen excepciones:

  • Oracle PL / SQL

  • Visual Basic clásico (V6 y abajo, "On Error Goto" es en mi humilde opinión una forma de manejo de excepciones)

(Para ser meticuloso: encuentra algunos elementos OO en ambos idiomas, pero la mecánica de manejo de excepciones no los utiliza, supongo que porque el concepto se introdujo años antes de que los elementos OO se agregaran a esos idiomas).

Doc Brown
fuente
Al menos las versiones posteriores de QuickBASIC en DOS (que precedieron a Visual Basic; QB 4.5 era 1988 según Wikipedia, VB 1.0 1991) tenían un manejo de errores usando la ON ERROR GOTOsintaxis. Incluso QuickBASIC tenía algunos conceptos similares a OO (creo que QB 4.5 incluso admitía clases de algún tipo), pero sería difícil llamar a BASIC en su mayoría tradicional un lenguaje orientado a objetos adecuado. [Wikipedia ]
un CVn
5

La idea básica detrás de las excepciones es limpiar el flujo del programa para que un programador pueda seguir la ruta de ejecución "normal" más fácilmente. Considere un caso simple de abrir un archivo en C. Inmediatamente después de intentar abrir el archivo, el programador necesita examinar la respuesta de la llamada fopen () y decidir si la llamada tuvo éxito. Si la llamada no tuvo éxito, entonces el programador debe responder adecuadamente. La siguiente llamada en la ruta de ejecución "normal", quizás una llamada a fread () o fwrite (), aparecerá después de que se hayan manejado las condiciones de error o falla. Eso puede estar en la siguiente pantalla.

Con un lenguaje que proporciona excepciones, la llamada a fopen () equivalente puede ser seguida inmediatamente por fread () o fwrite (). No hay manejo de errores que esté ocultando el "siguiente paso" de la ruta de ejecución "normal". El programador puede ver más de la ruta normal en una sola pantalla y, por lo tanto, puede seguir la ejecución más fácilmente. El manejo de errores se mueve a otra parte del programa.

Las excepciones en sí mismas no son un concepto de OOP, pero a menudo se implementan utilizando conceptos de OOP que los hacen más convenientes y potentes. Por ejemplo, las excepciones pueden definirse con una jerarquía de herencia. Utilizando nuestro ejemplo teórico de abrir y leer o escribir un archivo, cada una de esas llamadas puede generar una variedad de excepciones: FileClosedException, DeviceFullException, NoSuchFileException, InsufficientFilePermissionsException, etc. Cada una de ellas puede heredar de FileException, que puede heredar de IOException, que puede heredar de GenericException.

Si el programador está haciendo una implementación rápida y sucia para probar un concepto, puede ignorar la gestión de excepciones y simplemente implementar un controlador único para GenericException. Ese controlador manejará una GenericException y cualquier excepción que herede de GenericException. Si quiere tratar cualquier excepción relacionada con archivos de la misma manera, puede escribir un controlador para FileException. Eso se llamará para FileExceptions y cualquier excepción que herede de FileException. Si quiere escribir un programa que responda de manera diferente a una variedad de condiciones de error, puede escribir un controlador específico para cada excepción específica.

MikeD
fuente
3

Otros han respondido correctamente "No" con ejemplos de idiomas. Pensé que podría extender agregando un ejemplo sobre cómo agregar excepciones a un idioma sin involucrar a OOP.

Lo haré en el caso del DSKL (lenguaje de núcleo secuencial declarativo) de OZ , un lenguaje muy adecuado para cosas académicas como esta. El DSKL (o DKL) se puede ver aquí (resultado de búsqueda aleatorio), la parte de declaraciones y valores. La definición exacta no es importante, aparte de ser un lenguaje muy simple sin variables modificables (se declaran y luego se vinculan), y sin OOP incorporado.

OOP ni siquiera se puede agregar como una abstracción lingüística a este lenguaje kernel. Al agregar nombres únicos al idioma del kernel (NewName) y usar el alcance local, se puede lograr la encapsulación. O agregando un estado mutable al lenguaje del núcleo (NewCell) y utilizando el alcance local, se puede lograr una OOP adecuada con encapsulación. Pero no se puede lograr solo con el lenguaje del núcleo especificado.

Si luego agregamos excepciones al idioma del kernel, tendremos un idioma sin soporte de OOP pero tendremos excepciones. Déjame mostrarte cómo:

Al definir una máquina abstracta con una pila y un almacenamiento, podemos definir qué debe hacer cada declaración en nuestro lenguaje (la semántica de la declaración). Por ejemplo, skipen la pila no se debe hacer nada, A = 3en la pila se debe unir (/ unificar) A a (/ con) 3.

Comenzamos agregando la sintaxis de cómo deberían definirse nuestras excepciones. Hacemos esto agregando otras dos cláusulas <statement>en el DKL.

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

Aquí está el conocido try / catch, y una forma de aumentar / lanzar excepciones.

Definimos su semántica por cómo deberían funcionar en la máquina abstracta:

Probar
La declaración semántica es: (try <statement1> catch <id> then <statement2> end)
Hacer:

  1. Empuje sobre la pila la declaración semántica (catch <id> then <statement2> end)
  2. Empuje sobre la pila la declaración semántica (<statement1>)

Tenga en cuenta que la declaración 1 estará en la parte superior de la pila y se intentó ejecutar primero.

Elevar
La declaración semántica es: (raise <id> end)
Hacer:

  1. Si no hay nada más en la pila, deténgase e informe una excepción no detectada.
  2. De lo contrario, haga estallar la primera declaración semántica de la pila. Si no es una declaración catch, vaya al paso 1.
  3. Tenemos una trampa, en el formulario (catch <id> then <statement> end)
    Empuje (<statement>)hacia la pila.

Captura
Si vemos una instrucción catch durante la ejecución normal, esto significa que todo lo que se ejecutó en el interior sin generar excepciones hasta este nivel. Por lo tanto, solo sacamos catchla pila y no hacemos nada.

QED, tenemos un lenguaje con excepciones y sin posibilidad de OOP.

He eliminado la parte del entorno de la máquina abstracta para simplificarla.

Matsemann
fuente
1

No.

IIRC, las excepciones aparecieron antes de los primeros idiomas OO. AFAIK, las primeras implementaciones de LISP respaldaron las excepciones. Los primeros lenguajes estructurados (por ejemplo, ALGOL) y los primeros idiomas de OO (por ejemplo, SIMULA) no admitían excepciones.

Kevin Cline
fuente
ALGON 68, por supuesto, tenía excepciones ("eventos"), pero también tenía todo lo demás. PL / I también los tenía ("condiciones ON"), y hay literatura de 1969 que describe su uso.
Ross Patterson el