어제 게시물을 읽은 후 예외의 원인에 대해 많이 알지 못했다는 것을 깨달았습니다. OOP 관련 개념입니까? 나는 그것이 생각하는 경향이 있지만 다시 데이터베이스 예외가 있습니다.
goto
수행을 특히, 대상의. 던지기는 블록 구조의 중첩을 기반으로 컨텍스트에 따라 결정됩니다. 따라서 예외는 단일 출구 원칙이 지침으로 사용되지만 절대적이지는 않지만 다소 덜 엄격한 형태의 구조화 된 프로그래밍에 의존합니다.
어제 게시물을 읽은 후 예외의 원인에 대해 많이 알지 못했다는 것을 깨달았습니다. OOP 관련 개념입니까? 나는 그것이 생각하는 경향이 있지만 다시 데이터베이스 예외가 있습니다.
goto
수행을 특히, 대상의. 던지기는 블록 구조의 중첩을 기반으로 컨텍스트에 따라 결정됩니다. 따라서 예외는 단일 출구 원칙이 지침으로 사용되지만 절대적이지는 않지만 다소 덜 엄격한 형태의 구조화 된 프로그래밍에 의존합니다.
답변:
예외는 OOP 개념이 아닙니다.
그러나 그것들은 하나의 작은 지점에서 완전히 관련이 없습니다.
다른 답변에서 알 수 있듯이 : 예외 개념은 여러 비 OOP 언어로 예외를 만들었습니다. 이 개념 에는 OOP의 어떤 것도 필요 하지 않습니다 .
그러나 OOP를 진지하게 받아들이 는 모든 OOP 언어 가 예외를 요구 하는 것은 하나의 특정 지점에서 다른 오류 처리 방법이 실패하기 때문입니다.
OOP의 요점 중 하나는 객체가 내부 상태를 완전히 일관성있게 캡슐화하고 관리해야한다는 것입니다. 또한 순수한 OOP에서는 메모리 할당 (필요한 경우)부터 초기화까지, 의미있는 상태 (예 : 메모리 제로가 충분하지 않음)에 이르기까지 모든 상태가 "원자 적으로"존재하는 새로운 객체를 생성하는 개념이 필요 합니다. 한 가지 표현으로 이루어집니다. 따라서 생성자 가 필요합니다.
Foo myFoo = Foo("foo", "bar", 42);
그러나 이것은 약간의 오류로 인해 생성자가 실패 할 수도 있음을 의미합니다. 예외없이 생성자에서 오류 정보를 전파하는 방법은 무엇입니까?
반환 값? 일부 언어 에서는 의미있는 정보 new
만 반환 할 수 null
없으므로 실패 합니다. 다른 언어 (예 : C ++) myFoo
는 포인터가 아닙니다. 에 대해 확인할 수 없습니다 null
. 또한 myFoo
오류에 대해 물어볼 수 없습니다 . 오류가 초기화되지 않았으므로 OOP 사고에서 "존재하지 않습니다".
전역 오류 플래그? 상태를 캡슐화 한 다음 전역 변수를 사용하는 것이 어떻습니까? h ... ;-)로 이동
혼합물? 더 나은 방법은 없습니다.
?
따라서 예외는 OOP보다 더 기본적인 개념이지만 OOP는 자연스럽게 예외를 기반으로합니다.
OOP에만 관련이 있습니까?
아니요. 예외와 OOP는 관련이 없습니다.
예외 처리 는 오류를 처리하는 메커니즘입니다. 미리 정의 된 위치에 현재 실행 상태를 저장하고 예외 처리기라고하는 특정 서브 루틴으로 실행을 전환하여 예외를 처리합니다.
(C 비교 정말 OOP 언어 , C에서 어떻게 든 에뮬레이션 예외 수를 및 C ++ (OOP, 지원 예외)), C에 예외 처리를 추가하는 아무것도 방지 C의 표준위원회는 여전히 C OOP 언어하지 않습니다.
ON ERROR GOTO xxxx
try catch
구조를 생각합니다 .
예외적으로,주의를 기울여야하고 종종 프로그램 실행 흐름이 변경되는 예외적 인 상황이 예외입니다. 이 정의에 따라 예외 및 예외 처리는 객체 방향으로 제한되지 않으며 간단한 프로그램 오류는 예외 형태로 간주 될 수 있습니다.
객체 지향 언어에는 일반적으로 기본 예외 클래스가 있으며 문맥에 따라 "예외"라는 단어는 일반 개념 대신 해당 기본 클래스를 참조 할 수 있습니다. 객체 지향 예외 처리는 대부분 객체 지향과 마찬가지로 구문 설탕이며 결정적이지 않은 비 객체 지향 언어로 쉽게 에뮬레이션 할 수 있습니다. 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.");
}
}
대답은 단순한 NO입니다.
예외가 아닌 비 OO 언어의 좋은 예는 ADA입니다.
여기에 아주 좋은 답변이 있습니다. 예외가있는 비 OOP 프로그래밍 언어에 대한 다른 예 :
오라클 PL / SQL
기본 Visual Basic (V6 이하, "오류 발생시"는 IMHO 예외 처리 형식 임)
(즉, 두 언어 모두에서 일부 OO 요소를 찾을 수 있지만 예외 처리 메커니즘은 이들을 사용하지 않습니다. OO 요소가 해당 언어에 추가되기 몇 년 전에 개념이 도입 되었기 때문입니다).
ON ERROR GOTO
구문을 사용하여 오류를 처리했습니다 . QuickBASIC조차도 몇 가지 OO와 유사한 개념을 가지고 있었지만 (QB 4.5는 어떤 종류의 클래스를 지원한다고 생각합니다) 대부분의 전통적인 BASIC을 적절한 객체 지향 언어라고 부르기가 어려울 것입니다. [Wikipedia ]
예외의 기본 개념은 프로그래머가 "일반"실행 경로를보다 쉽게 따라갈 수 있도록 프로그램 흐름을 정리하는 것입니다. C에서 파일을 여는 간단한 경우를 고려하십시오. 파일을 열려고 시도한 직후 프로그래머는 fopen () 호출의 응답을 검사하고 호출이 성공했는지 여부를 결정해야합니다. 호출에 실패하면 프로그래머는 적절하게 응답해야합니다. "정상"실행 경로의 다음 호출, 아마도 fread () 또는 fwrite ()에 대한 호출은 오류 또는 실패 조건이 처리 된 후에 나타납니다. 다음 화면에있을 수 있습니다.
예외를 제공하는 언어를 사용하면 동등한 fopen () 호출 다음에 fread () 또는 fwrite ()가 바로 올 수 있습니다. "정상"실행 경로의 "다음 단계"를 숨기는 오류 처리는 없습니다. 프로그래머는 단일 화면에서 더 많은 일반 경로를 볼 수 있으므로 실행을 더 쉽게 수행 할 수 있습니다. 오류 처리는 프로그램의 다른 부분으로 이동됩니다.
예외 자체는 OOP 개념이 아니지만보다 편리하고 강력한 OOP 개념을 사용하여 구현되는 경우가 많습니다. 예를 들어, 예외는 상속 계층으로 정의 될 수 있습니다. 파일을 열고 읽거나 쓰는 일반적인 예제를 사용하면 이러한 각 호출은 FileException 예외, DeviceFullException, NoSuchFileException, 불충분 한 FilePermissionsException 등 다양한 예외를 생성 할 수 있습니다. 각 예외는 FileException에서 상속 될 수 있으며 IOException에서 상속 될 수 있습니다. GenericException에서 상속합니다.
프로그래머가 개념을 테스트하기 위해 빠르고 더러운 구현을 수행하는 경우 대부분 예외 처리를 무시하고 GenericException에 대한 단일 핸들러 만 구현할 수 있습니다. 이 핸들러는 GenericException 및 GenericException에서 상속되는 모든 예외를 처리합니다. 파일 관련 예외를 같은 방식으로 처리하려면 FileException에 대한 핸들러를 작성할 수 있습니다. FileException 및 FileException에서 상속되는 모든 예외에 대해 호출됩니다. 다양한 오류 조건에 다르게 응답하는 프로그램을 작성하려는 경우 각 특정 예외에 대해 특정 핸들러를 작성할 수 있습니다.
다른 사람들은 언어의 예를 들어 "아니오"라고 올바르게 대답했습니다. 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)
수행하십시오 :
(catch <id> then <statement2> end)
(<statement1>)
명령문 1은 스택의 맨 위에 있으며 먼저 실행을 시도합니다.
올리기
: 인 의미 문을 (raise <id> end)
해야 할 것 :
(catch <id> then <statement> end)
(<statement>)
.캐치
정상 실행 중에 캐치 명령문이 표시되면,이 레벨까지 예외를 발생시키지 않고 내부에서 실행 된 것이 무엇이든 의미합니다. 따라서 우리 catch
는 스택을 팝하고 아무것도하지 않습니다.
QED에는 예외가 있고 OOP 가능성이없는 언어가 있습니다.
더 간단하게하기 위해 추상 시스템에서 환경 부분을 제거했습니다.