구글은 유사한 양육 질문을 과 대답 내가 아주 좋은 생각. 아래에 인용했습니다.
여기에 숨겨져있는 쿡 에세이에 설명되어있는 또 다른 차이점이 있습니다.
객체가 추상화를 구현하는 유일한 방법은 아닙니다. 모든 것이 대상이 아닙니다. 객체는 일부 사람들이 절차 적 데이터 추상화라고하는 것을 구현합니다. 추상 데이터 형식은 다른 형태의 추상화를 구현합니다.
이진 방법 / 함수를 고려할 때 중요한 차이점이 나타납니다. 절차 적 데이터 추상화 (객체)를 사용하면 Int 세트 인터페이스에 다음과 같이 작성할 수 있습니다.
interface IntSet {
void unionWith(IntSet s);
...
}
이제 IntSet의 두 가지 구현을 고려하십시오. 하나는 목록으로 지원되고 다른 하나는보다 효율적인 이진 트리 구조로 지원됩니다.
class ListIntSet implements IntSet {
void unionWith(IntSet s){ ... }
}
class BSTIntSet implements IntSet {
void unionWith(IntSet s){ ... }
}
unionWith는 IntSet 인수를 가져야합니다. ListIntSet 또는 BSTIntSet과 같은 더 구체적인 유형은 아닙니다. 이것은 BSTIntSet 구현이 입력이 BSTIntSet이라고 가정 할 수 없으며 그 사실을 사용하여 효율적인 구현을 제공한다는 것을 의미합니다. (일부 런타임 유형 정보를 사용하여이를 확인하고 더 효율적인 알고리즘을 사용할 수는 있지만 여전히 ListIntSet에 전달 될 수 있으며 덜 효율적인 알고리즘으로 대체되어야합니다).
이것을 서명 또는 헤더 파일에 다음과 같은 것을 작성할 수있는 ADT와 비교하십시오.
typedef struct IntSetStruct *IntSetType;
void union(IntSetType s1, IntSetType s2);
이 인터페이스에 대해 프로그래밍합니다. 특히, 유형은 추상적입니다. 당신은 그것이 무엇인지 알지 못합니다. 그런 다음 BST 구현을 통해 구체적인 유형과 작업을 제공합니다.
struct IntSetStruct {
int value;
struct IntSetStruct* left;
struct IntSetStruct* right;
}
void union(IntSetType s1, IntSetType s2){ ... }
이제 Union은 실제로 s1과 s2의 구체적인 표현을 알고 있으므로 효율적인 구현을 위해이를 활용할 수 있습니다. 또한 목록 지원 구현을 작성하고 그 대신 연결하도록 선택할 수도 있습니다.
C (ish) 구문을 작성했지만 추상 데이터 형식 (예 : BSTImpl)을 정규화하여 대략 같은 프로그램에서 ADT의 구현을 두 개 이상 사용할 수있는 표준 ML을 참조해야합니다. IntSetStruct 및 ListImpl.IntSetStruct)
반대로 절차 데이터 추상화 (오브젝트)를 사용하면 이전 구현에서 작동하는 새로운 구현을 쉽게 도입 할 수 있습니다. 예를 들어, 사용자 정의 LoggingIntSet 구현을 작성하고이를 BSTIntSet과 통합 할 수 있습니다. 그러나 이것은 트레이드 오프입니다. 바이너리 방법에 대한 정보 유형을 잃어 버립니다! 종종 ADT 구현보다 더 많은 기능 및 구현 세부 사항을 인터페이스에 노출해야합니다. 이제 저는 쿡 에세이를 다시 입력하는 것처럼 느껴지므로 실제로 읽으십시오!
이에 대한 예를 추가하고 싶습니다.
Cook은 추상 데이터 형식의 예는 C의 모듈이라고 제안합니다. 실제로 C의 모듈에는 헤더 파일을 통해 내보내는 공용 함수와 그렇지 않은 정적 (비공개) 함수가 있기 때문에 정보 숨기기가 필요합니다. 또한 생성자 (예 : list_new ())와 관찰자 (예 : list_getListHead ())가 있습니다.
예를 들어 LIST_MODULE_SINGLY_LINKED라는 목록 모듈을 ADT로 만드는 핵심 요소는 모듈의 기능 (예 : list_getListHead ())이 "동일한 항목과 달리 LIST_MODULE_SINGLY_LINKED의 생성자에 의해 입력되는 데이터가 생성되었다고 가정한다는 것입니다 "목록 구현 (예 : LIST_MODULE_DYNAMIC_ARRAY). 이는 LIST_MODULE_SINGLY_LINKED의 기능이 구현시 특정 표현 (예 : 단일 링크 목록)을 가정 할 수 있음을 의미합니다.
LIST_MODULE_SINGLY_LINKED는 LIST_MODULE_DYNAMIC_ARRAY 생성자와 같이 생성 된 데이터를 피드 할 수 없기 때문에 LIST_MODULE_DYNAMIC_ARRAY와 상호 운용 할 수 없습니다.
이것은 추상 대수학에서 서로 다른 두 그룹이 상호 운용 할 수없는 방식과 유사합니다 (즉, 한 그룹의 요소를 다른 그룹의 요소와 곱할 수 없음). 이는 그룹이 그룹의 폐쇄 속성을 가정하기 때문입니다 (그룹의 요소 곱은 그룹에 있어야 함). 그러나 두 개의 다른 그룹이 실제로 다른 그룹 G의 하위 그룹임을 증명할 수있는 경우 G의 곱을 사용하여 두 그룹 각각에서 하나씩 두 개의 요소를 추가 할 수 있습니다.
ADT와 객체 비교
Cook은 ADT와 객체의 차이를 부분적으로 표현 문제에 연결합니다.. 대략 ADT는 함수형 프로그래밍 언어로 구현되는 일반 기능과 연결되는 반면 객체는 인터페이스를 통해 액세스하는 Java "객체"와 연결됩니다. 이 텍스트의 목적 상, 일반 함수는 ARGS와 TYPE 유형 (사전 조건)을 일부 인수로받는 함수입니다. TYPE에 따라 적절한 기능을 선택하고 ARGS (사후 조건)로 평가합니다. 일반 함수와 객체는 다형성을 구현하지만 일반 함수를 사용하면 일반 함수의 코드를 보지 않고 일반 함수에 의해 함수가 실행되는 프로그래머 KNOWS가 있습니다. 반면에 객체를 사용하면 프로그래머가 객체의 코드를 보지 않는 한 객체가 인수를 처리하는 방법을 프로그래머가 알지 못합니다.
일반적으로 표현 문제는 "많은 표현이 있습니까?"의 관점에서 생각됩니다. vs. "표현이 거의없는 많은 기능이 있습니까?" 첫 번째 경우, 가장 일반적으로, 특히 Java에서와 같이 표현별로 코드를 구성해야합니다. 두 번째 경우에는 함수별로 코드를 구성해야합니다 (즉, 단일 일반 함수가 여러 표현을 처리 함).
코드를 표현별로 구성한 경우 추가 기능 을 추가하려면 객체의 모든 표현에 기능을 추가 해야 합니다. 이런 의미에서 기능 추가는 "첨가"가 아닙니다. 기능별로 코드를 구성하는 경우 추가 표현을 추가하려는 경우 모든 객체에 표현을 추가 해야 합니다. 이런 의미에서 "첨가"가 아닌 표현을 추가합니다.
개체에 비해 ADT의 장점
ADT에 비해 개체의 장점
동적 디스패치는 OOP의 핵심
동적 디스패치 (즉, 후기 바인딩)는 객체 지향 프로그래밍에 필수적이라는 것이 명백 해졌다. 이것은 특정 표현을 가정하지 않는 일반적인 방법으로 프로 시저를 정의 할 수 있도록하기위한 것입니다. 구체적인 객체 지향 프로그래밍은 파이썬에서 쉽습니다. 특정 표현을 가정하지 않는 방식으로 객체의 메소드를 프로그래밍 할 수 있기 때문입니다. 그렇기 때문에 파이썬에는 Java와 같은 인터페이스가 필요하지 않습니다.
Java에서 클래스는 ADT입니다. 그러나 구현하는 인터페이스를 통해 액세스되는 클래스는 객체입니다.
부록 : Alan Kay의 OOP 버전
Alan Kay는 개체를 대수의 가족이라고 명시 적으로 언급했으며 Cook은 ADT가 대수라고 제안합니다. 따라서 Kay는 개체가 ADT의 패밀리라는 것을 의미했을 것입니다. 즉, 객체는 Java 인터페이스를 만족시키는 모든 클래스의 모음입니다.
그러나 Cook이 그린 물체 그림은 Alan Kay의 비전보다 훨씬 제한적입니다. 그는 객체가 네트워크의 컴퓨터 또는 생물학적 세포처럼 행동하기를 원했습니다. 아이디어는 프로그래밍에 대한 최소한의 노력의 원칙을 적용하여 상위 계층을 사용하여 ADT의 하위 계층을 쉽게 변경하도록하는 것이 었습니다. 이 그림을 염두에두고, Java 인터페이스는 객체가 메시지의 의미를 해석 하거나 완전히 무시할 수 없기 때문에 너무 제한적 입니다.
요약하자면, Kay의 객체의 핵심 아이디어는 객체 가 대수 군이라는 것이 아닙니다 (쿡이 강조한 것처럼). Kay의 핵심 아이디어는 대형 (네트워크의 컴퓨터)에서 작동하는 모델을 소형 (프로그램의 객체)에 적용하는 것이 었습니다.
편집 : Kay의 OOP 버전에 대한 또 다른 설명 : 객체의 목적은 선언적 이상에 더 가깝게 이동하는 것입니다. 절차 적 프로그래밍과 ADT의 관습과 같이 마이크로 매니지먼트가 어떻게 상태 인지를 말하지 말고 객체에게 무엇을해야하는지 알려 주어야합니다 . 자세한 내용은 여기 , 여기 , 여기 및 여기를 참조하십시오 .
편집 : Alan Kay의 OOP 정의에 대한 매우 훌륭한 설명을 찾았 습니다 .