예외가 OOP 개념입니까?


37

어제 게시물을 읽은 후 예외의 원인에 대해 많이 알지 못했다는 것을 깨달았습니다. OOP 관련 개념입니까? 나는 그것이 생각하는 경향이 있지만 다시 데이터베이스 예외가 있습니다.


나는 "Mr Goodenuf"(또는 이와 유사한)가 "마음이 아니라면 Goodenuf, eh!" 괴롭힘 스타일. 지금은 참조를 찾을 수 없습니다. 다른 사람이 할 수 있습니다. 그들이 어떤 언어를 처음 추가했는지 아는 것은 흥미로울 것입니다.
Steve314

7
하스켈은 예외가 있으며 전혀 OOP가 아닙니다
jozefg

1
예외 자체가 엄격하게 객체 지향적이지는 않지만 예외를 객체로 정의하고 이러한 객체의 인스턴스를 명확하게 던지고 잡는 일반적인 관행은 매우 OOP입니다.
Dougvj

예외와 GOTO의 차이점은 흥미로운 질문입니다.
Austin Henley

2
@Austin - 방법 "에 대한 예외는 절대 같은 구조화 프로그래밍 옹호의 엄격한 제자들 중 일부는, 그들은이 방법으로 구속 스파게티 제어 흐름을 허용하지 않는 것이 하나의 출구 지점의 원칙에 위배가 발생하더라도 goto수행을 특히, 대상의. 던지기는 블록 구조의 중첩을 기반으로 컨텍스트에 따라 결정됩니다. 따라서 예외는 단일 출구 원칙이 지침으로 사용되지만 절대적이지는 않지만 다소 덜 엄격한 형태의 구조화 된 프로그래밍에 의존합니다.
Steve314

답변:


5

예외는 OOP 개념이 아닙니다.

그러나 그것들은 하나의 작은 지점에서 완전히 관련이 없습니다.

다른 답변에서 알 수 있듯이 : 예외 개념은 여러 비 OOP 언어로 예외를 만들었습니다. 이 개념 에는 OOP의 어떤 것도 필요 하지 않습니다 .

그러나 OOP를 진지하게 받아들이 는 모든 OOP 언어 가 예외를 요구 하는 것은 하나의 특정 지점에서 다른 오류 처리 방법이 실패하기 때문입니다.

OOP의 요점 중 하나는 객체가 내부 상태를 완전히 일관성있게 캡슐화하고 관리해야한다는 것입니다. 또한 순수한 OOP에서는 메모리 할당 (필요한 경우)부터 초기화까지, 의미있는 상태 (예 : 메모리 제로가 충분하지 않음)에 이르기까지 모든 상태가 "원자 적으로"존재하는 새로운 객체를 생성하는 개념이 필요 합니다. 한 가지 표현으로 이루어집니다. 따라서 생성자 가 필요합니다.

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

그러나 이것은 약간의 오류로 인해 생성자가 실패 할 수도 있음을 의미합니다. 예외없이 생성자에서 오류 정보를 전파하는 방법은 무엇입니까?

  • 반환 값? 일부 언어 에서는 의미있는 정보 new만 반환 할 수 null없으므로 실패 합니다. 다른 언어 (예 : C ++) myFoo는 포인터가 아닙니다. 에 대해 확인할 수 없습니다 null. 또한 myFoo오류에 대해 물어볼 수 없습니다 . 오류가 초기화되지 않았으므로 OOP 사고에서 "존재하지 않습니다".

  • 전역 오류 플래그? 상태를 캡슐화 한 다음 전역 변수를 사용하는 것이 어떻습니까? h ... ;-)로 이동

  • 혼합물? 더 나은 방법은 없습니다.

  • ?

따라서 예외는 OOP보다 더 기본적인 개념이지만 OOP는 자연스럽게 예외를 기반으로합니다.


3
내가 알 수있는 한,이 "답변"에서 실제 질문을 다루는 유일한 단어는 "아니오"입니다. 이 어딘가에 사이 읽고 나에게 외람된 - 나머지는 OOP의 예외에 대한 것으로 보인다 막연하게 관련완전히 무관 - 질문의 맥락에서 다시를 요청
모기

@gnat : TO는 또한 예외의 기원에 대해 모른다고 말합니다. 따라서 왜 OO 땅의 모든 곳에서 예외가 발생했는지에 대한 약간의 배경은 나에게 괜찮은 것처럼 보였습니다. YMMV
AH

1
@AH 나는 개막 라인을 제외하고는 모기에 동의해야하며, 실제로 질문을 다루지 않습니다. gnat에 대한 귀하의 응답은 "예외의 출처에 대해 모른다"고 말했지만 실제로 예외의 출처를 제시하지 않았으며 객체 인스턴스화 중에 예외를 무작위로 사용했습니다.

여러분 진심 으로요? -1? 다른 답변도 대부분 100 %가 아닙니다. 보상하기 위해 +1 이 답변은 깨진 클래스 디자인의 세계에서 좋은 배경 조언을 제공합니다. (개정 : 다단계 생성자를 언급하지 말아야한다)
Jo So

44

OOP에만 관련이 있습니까?

아니요. 예외와 OOP는 관련이 없습니다.

예외 처리 는 오류를 처리하는 메커니즘입니다. 미리 정의 된 위치에 현재 실행 상태를 저장하고 예외 처리기라고하는 특정 서브 루틴으로 실행을 전환하여 예외를 처리합니다.

(C 비교 정말 OOP 언어 , C에서 어떻게 든 에뮬레이션 예외 수를 및 C ++ (OOP, 지원 예외)), C에 예외 처리를 추가하는 아무것도 방지 C의 표준위원회는 여전히 C OOP 언어하지 않습니다.


2
일반적인 OS에서 이미 지원되는 예외가 있다고 주장 할 수도 있습니다. 프로그램이 중단되도록 (잡히지 않은 "예외") 코어 덤프와 디버거를 사용하면 스택 추적을 얻을 수도 있습니다.
bhaak

12
80 년대 초반의 MS BASIC조차도 예외 처리가있었습니다 :ON ERROR GOTO xxxx
jwernerny

1
@bhaak 그는 Windows에서 메모리 덤프에 대해 이야기 할 수도 있습니다
JohnL

11
@jwernerny 오류 처리? 확실한. 그러나 아무도 예외 처리를 호출하지 않습니다. 실제로, (구조화 된) 예외 처리 는 일상적으로 대조 되었습니다.
Konrad Rudolph

1
@jwernerny 내가 확실하지 않은; 내가 이해했듯이 예외 처리는 오류 처리를 수행하는 매우 구체적인 방법입니다. 예외가 들리면 항상 try catch구조를 생각합니다 .
Andy

12

예외적으로,주의를 기울여야하고 종종 프로그램 실행 흐름이 변경되는 예외적 인 상황이 예외입니다. 이 정의에 따라 예외 및 예외 처리는 객체 방향으로 제한되지 않으며 간단한 프로그램 오류는 예외 형태로 간주 될 수 있습니다.

객체 지향 언어에는 일반적으로 기본 예외 클래스가 있으며 문맥에 따라 "예외"라는 단어는 일반 개념 대신 해당 기본 클래스를 참조 할 수 있습니다. 객체 지향 예외 처리는 대부분 객체 지향과 마찬가지로 구문 설탕이며 결정적이지 않은 비 객체 지향 언어로 쉽게 에뮬레이션 할 수 있습니다. C 프로그래밍 위키 북 의 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.");
    }
}

6
그것은 단지 구문 설탕이 아닙니다. setjmp를 사용하면 전체 스택 해제 및 유형 기반 캐치 핸들러를 다시 작성하기가 어렵습니다. 또한 예외의 특수 컴파일은 setjmp로 모방 할 수없는 이점을 제공합니다.
edA-qa mort-ora-y

3
예외 예외는 예외적 인 상황입니다. 오히려 현재 상황에서 오류를 올바르게 수정하기에 충분한 정보가 없기 때문에 현재 상황에서 오류 상황을 해결할 수없는 경우 예외가 발생 (발생)해야한다고 말합니다.
Martin York


9

대답은 단순한 NO입니다.

예외가 아닌 비 OO 언어의 좋은 예는 ADA입니다.


4
ADA가 왜 OO 언어가 아닌가? 물론 ADA83에는 다형성이 없었지만 여전히 객체 기반으로 간주 될 수 있습니다. 또한 ADA95 이후 언어는 완전히 객체 지향적입니다.
yannis

내가 아는 한 예외 처리가 ADA83보다 오래되었으므로 ADA 자체는 예외 처리가 아닌 비 OO입니다.
Uwe Plonus

2
@YannisRizos : Ada83에는 패키지와 일반 패키지가 있지만 객체는 없습니다. 그들은 Ada95와 함께 소개되었습니다.
mouviciel

2
@Yannis-다형성이없는 객체는 중첩 블록이없는 구조화 된 프로그래밍과 같습니다. 다형성은 OOP의 정의 특성 중 하나입니다. Ada95에서도 런타임 바인딩을 지원하는 유형을 "클래스"가 아니라 "태그 유형"이라고합니다 (물론 철자법 임). Ada 83에는 변형 레코드 및 기타 다양한 유형이 있었지만 해당 유형 중 어느 것도 OOP에 특정한 기능을 제공하지 않습니다. Ada 83은 모듈 식이고 구조적이지만 객체 지향적이지 않았습니다.
Steve314

3
@Yannis-기본적으로 Ada 커뮤니티의 일부 사람들은 (대부분의 언어를 옹호하는 사람들과 같이) 기능이 훌륭하지만 자신이 좋아하는 언어로 구현할 수 없다는 것을 받아 들일 수 없으며 달리 믿는 것을위한 모든 종류의 변명을 구성합니다. 그러나 좋은 언어가 가능한 모든 좋은 언어 기능을 가져야 할 필요는 없습니다 (Ada 디자이너가 그렇게 생각했다고 믿기는 쉽지만). 나는 언어 설계에 대한 미니멀리스트 접근법을 실제로 믿는 사람은 아니지만 최대주의 언어도 완벽하지 않습니다.
Steve314

7

여기에 아주 좋은 답변이 있습니다. 예외가있는 비 OOP 프로그래밍 언어에 대한 다른 예 :

  • 오라클 PL / SQL

  • 기본 Visual Basic (V6 이하, "오류 발생시"는 IMHO 예외 처리 형식 임)

(즉, 두 언어 모두에서 일부 OO 요소를 찾을 수 있지만 예외 처리 메커니즘은 이들을 사용하지 않습니다. OO 요소가 해당 언어에 추가되기 몇 년 전에 개념이 도입 되었기 때문입니다).


DOS의 최신 QuickBASIC 버전 (Visual Basic보다 우선 함; QB 4.5는 Wikipedia, VB 1.0 1991에 따르면 1988 임)은 ON ERROR GOTO구문을 사용하여 오류를 처리했습니다 . QuickBASIC조차도 몇 가지 OO와 유사한 개념을 가지고 있었지만 (QB 4.5는 어떤 종류의 클래스를 지원한다고 생각합니다) 대부분의 전통적인 BASIC을 적절한 객체 지향 언어라고 부르기가 어려울 것입니다. [Wikipedia ]
CVn

5

예외의 기본 개념은 프로그래머가 "일반"실행 경로를보다 쉽게 ​​따라갈 수 있도록 프로그램 흐름을 정리하는 것입니다. C에서 파일을 여는 간단한 경우를 고려하십시오. 파일을 열려고 시도한 직후 프로그래머는 fopen () 호출의 응답을 검사하고 호출이 성공했는지 여부를 결정해야합니다. 호출에 실패하면 프로그래머는 적절하게 응답해야합니다. "정상"실행 경로의 다음 호출, 아마도 fread () 또는 fwrite ()에 대한 호출은 오류 또는 실패 조건이 처리 된 후에 나타납니다. 다음 화면에있을 수 있습니다.

예외를 제공하는 언어를 사용하면 동등한 fopen () 호출 다음에 fread () 또는 fwrite ()가 바로 올 수 있습니다. "정상"실행 경로의 "다음 단계"를 숨기는 오류 처리는 없습니다. 프로그래머는 단일 화면에서 더 많은 일반 경로를 볼 수 있으므로 실행을 더 쉽게 수행 할 수 있습니다. 오류 처리는 프로그램의 다른 부분으로 이동됩니다.

예외 자체는 OOP 개념이 아니지만보다 편리하고 강력한 OOP 개념을 사용하여 구현되는 경우가 많습니다. 예를 들어, 예외는 상속 계층으로 정의 될 수 있습니다. 파일을 열고 읽거나 쓰는 일반적인 예제를 사용하면 이러한 각 호출은 FileException 예외, DeviceFullException, NoSuchFileException, 불충분 한 FilePermissionsException 등 다양한 예외를 생성 할 수 있습니다. 각 예외는 FileException에서 상속 될 수 있으며 IOException에서 상속 될 수 있습니다. GenericException에서 상속합니다.

프로그래머가 개념을 테스트하기 위해 빠르고 더러운 구현을 수행하는 경우 대부분 예외 처리를 무시하고 GenericException에 대한 단일 핸들러 만 구현할 수 있습니다. 이 핸들러는 GenericException 및 GenericException에서 상속되는 모든 예외를 처리합니다. 파일 관련 예외를 같은 방식으로 처리하려면 FileException에 대한 핸들러를 작성할 수 있습니다. FileException 및 FileException에서 상속되는 모든 예외에 대해 호출됩니다. 다양한 오류 조건에 다르게 응답하는 프로그램을 작성하려는 경우 각 특정 예외에 대해 특정 핸들러를 작성할 수 있습니다.


3

다른 사람들은 언어의 예를 들어 "아니오"라고 올바르게 대답했습니다. OOP를 사용하지 않고 언어에 예외를 추가하는 방법에 대한 예를 추가하여 확장 할 수 있다고 생각했습니다.

OZ 의 DSKL (Declarative Sequential Kernel Language)의 경우 , 이런 식으로 학계에 적합한 언어입니다. DSKL (또는 DKL)은 Statements and Values ​​부분에서 볼 수 있습니다 (무작위 검색 결과). 정확한 정의는 중요하지 않습니다. 이것은 수정 가능한 변수가 없으며 (선언되고 나중에 바인드 됨) OOP가 내장되어 있지 않은 매우 간단한 언어입니다.

이 커널 언어에 대한 언어 적 추상화로 OOP를 추가 할 수도 없습니다. 커널 언어 (NewName)에 고유 한 이름을 추가하고 로컬 범위를 사용하면 캡슐화를 수행 할 수 있습니다. 또는 커널 언어 (NewCell)에 변경 가능한 상태를 추가하고 로컬 범위 지정을 사용하여 캡슐화와 함께 적절한 OOP를 달성 할 수 있습니다. 그러나 지정된 커널 언어만으로는 달성 할 수 없습니다 .

커널 언어에 예외를 추가하면 OOP 지원은 없지만 예외는있는 언어가됩니다. 방법을 보여 드리겠습니다.

스택과 스토리지를 가진 추상 머신을 정의함으로써, 우리는 언어로 된 각 문장이 무엇을해야하는지 정의 할 수 있습니다 ( 구문의미론 ). 예를 들어 skip스택에서 아무것도하지 않아야합니다. 스택 A = 3에서 A를 (/ with) 3에 바인딩 (/ 통합)해야합니다.

먼저 예외를 정의하는 방법에 대한 구문 을 추가하는 것으로 시작합니다 . 우리는 <statement>DKL에 또 다른 두 개의 절을 추가하여이를 수행합니다 .

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

알려진 try / catch와 예외를 발생 시키거나 발생시키는 방법이 있습니다.

우리는 그것들이 추상 머신에서 어떻게 동작해야하는지에 따라 의미 를 정의 합니다 :

시도
의미 론적 문을되어 (try <statement1> catch <id> then <statement2> end)
수행하십시오 :

  1. 의미 문을 스택에 푸시 (catch <id> then <statement2> end)
  2. 의미 문을 스택에 푸시 (<statement1>)

명령문 1은 스택의 맨 위에 있으며 먼저 실행을 시도합니다.

올리기
: 인 의미 문을 (raise <id> end)
해야 할 것 :

  1. 스택에 더 이상 아무것도 없으면 잡히지 않은 예외를 중지하고보고하십시오.
  2. 그렇지 않으면 스택에서 첫 번째 의미 문장을 팝하십시오. catch 문이 아닌 경우 1 단계로 이동하십시오.
  3. 우리는 스택에 (catch <id> then <statement> end)
    푸시 형태로 캐치를 얻었습니다 (<statement>).

캐치
정상 실행 중에 캐치 명령문이 표시되면,이 레벨까지 예외를 발생시키지 않고 내부에서 실행 된 것이 무엇이든 의미합니다. 따라서 우리 catch는 스택을 팝하고 아무것도하지 않습니다.

QED에는 예외가 있고 OOP 가능성이없는 언어가 있습니다.

더 간단하게하기 위해 추상 시스템에서 환경 부분을 제거했습니다.


1

아니.

IIRC, 첫 번째 OO 언어 전에 예외가 나타났습니다. AFAIK, 예외는 초기 LISP 구현에서 처음으로 지원되었습니다. 초기 구조 언어 (예 : ALGOL) 및 초기 OO 언어 (예 : SIMULA)는 예외를 지원하지 않았습니다.


물론 ALGON 68에는 예외 ( "이벤트")가 있었지만 다른 것 역시있었습니다. PL / I도 그것들을 가지고 있었으며 ( "ON conditions") 1969 년부터 그것들의 사용법을 기술 한 문헌이 있습니다.
로스 패터슨
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.