첫 학기에는 Java 및 UML을 통해 캡슐화, 데이터 숨기기, 모듈화, 상속 등과 같은 OOP 개념을 소개했습니다. (자바는 나의 첫 프로그래밍 언어이다)
이들 중 어느 것도 OOP 개념이 아닙니다. 그것들은 모두 OO와 독립적으로 OO 외부에 존재하며 심지어 OO 이전에도 발명되었습니다.
그래서, 당신은 아니라고 생각하면 그 OO이, 모두에 대해 다음 결론은 옳은 일이다 : 당신은 절차 적 언어로 사람들의 모든 작업을 수행 할 수 있습니다 그들이 OO와는 아무 상관이 없기 때문에 .
예를 들어, 모듈성에 관한 주요 논문 중 하나는 시스템을 모듈로 분해하는 데 사용되는 기준 에 관한 것 입니다. 거기에 OO에 대한 언급이 없습니다. (이것은 1972 년에 쓰여졌으며 그때까지 OO는 이미 10 년이 넘었음에도 불구하고 여전히 모호한 틈새 시장이었습니다.)
하지만 데이터 추상화는 OO에서 중요하다, 그것은 더입니다 결과 가 결정적인 기능을보다 OO (메시징)의 주요 기능. 또한 서로 다른 종류 의 데이터 추상화 가 있다는 것을 기억하는 것이 매우 중요합니다 . 오늘날 사용되는 가장 일반적인 두 종류의 데이터 추상화는 (다른 두 가지 결합보다 여전히 사용되는 "추상화 없음"을 무시하는 경우) Abstract Data Types and Objects 입니다. 따라서 "Information Hiding", "Encapsulation"및 "Data Abstraction"이라고 말하면 OO는 데이터 추상화의 한 형태 일 뿐이며 두 가지가 근본적으로 다릅니다.
- 추상 데이터 형식에서 추상화 메커니즘은 형식 시스템입니다 . 구현을 숨기는 타입 시스템입니다. 유형 시스템이 반드시 정적 일 필요는 없습니다. Objects를 사용하면 구현이 유형이 필요하지 않은 절차 적 인터페이스 뒤에 숨겨집니다 . 예를 들어 ECMAScript에서와 같이 클로저로 구현할 수 있습니다.
- 추상 데이터 형식을 사용하면 서로 다른 ADT의 인스턴스가 서로 캡슐화되지만 동일한 ADT의 인스턴스는 서로의 표현 및 개인 구현을 검사하고 액세스 할 수 있습니다. 객체는 항상 모든 것에서 캡슐화됩니다 . 객체 자체 만 자체 표현을 검사하고 자체 구현에 액세스 할 수 있습니다. 다른 객체 , 같은 유형의 다른 객체, 같은 클래스의 다른 인스턴스, 동일한 프로토 타입을 가진 다른 객체, 객체의 복제본 등이 불가능합니다. 없음 .
이것이 의미하는 바는 Java에서 클래스는 객체 지향적이지 않다는 것입니다. 동일한 클래스의 두 인스턴스는 서로의 표현 및 개인 구현에 액세스 할 수 있습니다. 따라서 클래스의 인스턴스는 개체가 아니며 실제로 ADT 인스턴스입니다. 자바 interface
의, 그러나 않는 객체 지향 데이터 추상화를 제공한다. 즉, 인터페이스의 인스턴스 만 Java의 객체이고 클래스의 인스턴스는 그렇지 않습니다.
기본적으로 유형의 경우 인터페이스 만 사용할 수 있습니다. 이는 매개 변수 유형의 메소드 및 생성자, 리턴 유형의 메소드, 인스턴스 필드 유형, 정적 필드 및 로컬 필드, instanceof
연산자 또는 캐스트 연산자에 대한 인수 및 일반 유형 생성자에 대한 유형 인수는 항상 인터페이스 여야합니다. 클래스는 new
연산자 바로 뒤에 만 사용할 수 있습니다 .
예를 들어 모듈성을 위해 프로그램을 별도의 파일에 포함 된 잘 정의 된 작업을 수행하는 여러 개의 작은 프로그램으로 나눌 수 있습니다. 이러한 프로그램은 잘 정의 된 입력 및 출력을 통해 서로 상호 작용합니다. 캡슐화를 위해 파일을 보호 (암호화) 할 수 있습니다. 코드 재사용을 위해 새 프로그램에서 필요할 때마다 해당 파일을 호출 할 수 있습니다. 이것이 OOP가 무엇인지 모두 포착하지 못합니까? 아니면 매우 분명한 것이 빠져 있습니까?
당신이 설명하는 것은 OO입니다.
그것은 실제로 OO를 생각하는 좋은 방법입니다. 사실, 그것은 OO의 최초 발명가들이 생각했던 것과 거의 똑같습니다. (Alan Kay는 한 걸음 더 나아갔습니다. 그는 네트워크를 통해 서로에게 메시지를 보내는 많은 작은 컴퓨터를 구상했습니다.) "프로그램"이라고하는 것은 일반적으로 "개체"라고하며 "통화"대신 일반적으로 "메시지 보내기"라고 말합니다. ".
객체 지향은 메시징 (일명 동적 디스패치 )에 관한 것입니다. "객체 지향"이라는 용어는 스몰 토크의 수석 디자이너 인 Alan Kay 박사가 만든 것으로 다음과 같이 정의합니다 .
나에게 OOP는 메시징, 로컬 보존 및 상태 프로세스 숨기기 및 모든 것의 늦게 바인딩을 의미합니다.
그것을 분해하자 :
- 메시징 (Smalltalk에 익숙하지 않은 경우 "가상 메소드 디스패치")
- 상태 프로세스는
- 모든 것의 극단적 인 구속력
구현 현명한, 메시징은 런타임에 바인딩 된 프로 시저 호출, 그리고 프로 시저 호출은 런타임에 바인딩하는 경우, 당신은 디자인 타임에 알 수없는 어떤 전화 할거야, 그래서 당신은 국가의 구체적인 표현에 대한 가정을 만들 수 없습니다. 따라서 실제로 메시징에 관한 것입니다. 후기 바인딩은 메시징의 구현이며 캡슐화는 그 결과입니다.
그는 나중에 " 큰 아이디어는 '메시징' "이라고 설명하고 "개체 지향"이라는 용어가 중요하지 않은 것에 중점을두기 때문에 "메시지 지향"대신 "개체 지향"이라고 불렀습니다. ) 및 실제로 중요한 사항 (메시지)을 산만하게합니다.
마지막 OOPSLA에서 스몰 토크가 구문이나 클래스 라이브러리뿐만 아니라 클래스에 관한 것도 아니라는 사실을 모든 사람들에게 상기시키기 위해 약간의 고통을 겪었다는 것을 상기시켜줍니다. 오래 전에이 주제에 대해 "개체"라는 용어를 만들어서 유감스럽게 생각합니다.
큰 아이디어는 "메시징 (messaging)"입니다. 이것이 스몰 토크 / 스 퀘이크의 핵심이되는 것입니다 (그리고 우리의 제록스 PARC 단계에서 결코 완성되지 않은 것입니다). 일본인은 "가장 중간에있는"이라는 단어가 작습니다. 아마도 가장 가까운 영어 단어는 "삽입 광고"입니다. 훌륭하고 확장 가능한 시스템을 만드는 데있어 핵심은 내부 속성과 동작이 아닌 모듈이 통신하는 방식을 디자인하는 것보다 훨씬 더 중요합니다. 인터넷을 생각하십시오. 살기 위해서는 (a) 단일 표준을 넘어서는 많은 다른 종류의 아이디어와 실현을 허용해야하고 (b) 이러한 아이디어들간에 다양한 정도의 안전한 상호 운용성을 허용해야합니다.
(물론 오늘날 대부분의 사람들은 사물에 초점을 맞추지 않고 수업에 집중합니다.
메시지는 은유 및 메커니즘으로 OO의 기본 입니다.
누군가에게 메시지를 보내면 상대방이하는 일을 알 수 없습니다. 관찰 할 수 있는 유일한 것은 그들의 반응입니다. 메시지 자체를 처리했는지 (예 : 객체에 메소드가있는 경우), 메시지를 다른 사람에게 전달한 경우 (위임 / 프록시) 모르는 경우 알 수 없습니다. 그것이 캡슐화의 모든 것입니다. 그것이 OO의 모든 것입니다. 프록시가 예상대로 응답하는 한 프록시를 실제와 구별 할 수 없습니다.
"메시징"에 대한 "현대적인"용어는 "동적 메소드 디스패치"또는 "가상 메소드 호출"이지만 은유를 잃고 메커니즘에 중점을 둡니다.
따라서 Alan Kay의 정의를 보는 두 가지 방법이 있습니다. 독자적으로보고있는 경우 메시징은 기본적으로 지연된 프로 시저 호출이고 지연 바인딩은 캡슐화를 의미하므로 # 1을 결론 지을 수 있습니다. # 2는 실제로 중복되며 OO는 늦게 바인딩됩니다.
그러나 나중에 중요한 것은 메시징이라는 점을 명확하게 밝혔으므로 다른 관점에서 볼 수 있습니다. 메시징은 지연됩니다. 이제 메시징이 유일 하게 가능하다면 # 3은 사실 일 것입니다. 단 하나만 있고 그 것이 늦으면 모든 것이 늦습니다. 그리고 다시 한 번 캡슐화는 메시징에서 따릅니다.
윌리엄 R. 쿡 (William R. Cook)이 재검토 한 On Understanding Data Abstraction 에서도 비슷한 점을 지적 하고 있으며 "개체"와 "개체 지향"에 대한 단순화 된 현대적 정의에 대한 그의 제안 :
작업의 동적 디스패치는 객체의 필수 특성입니다. 이는 호출되는 조작이 오브젝트 자체의 동적 특성임을 의미합니다. 오퍼레이션은 정적으로 식별 될 수 없으며, 일반적으로 오퍼레이션을 실행하는 것을 제외하고는 주어진 요청에 응답하여 어떤 오퍼레이션이 실행 될지 정확히 알 수있는 방법이 없습니다. 이것은 항상 동적으로 전달되는 일급 함수와 동일합니다.
스몰 토크 -72에는 아무 물체도 없었습니다! 파싱, 재 작성 및 재 라우팅 된 메시지 스트림 만 있었습니다 . 처음에는 메소드 (메시지 스트림을 구문 분석하고 다시 라우팅하는 표준 방법)가 왔으며 나중에 오브젝트 (일부 개인 상태를 공유하는 메소드 그룹)가 나왔습니다. 상속은 훨씬 후에 왔으며 상속을 지원하는 방법으로 만 수업이 도입되었습니다. Kay의 리서치 그룹이 이미 프로토 타입에 대해 알고 있었다면 아마도 처음에는 수업을 소개하지 않았을 것입니다.
유형 및 프로그래밍 언어의 Benjamin Pierce 는 객체 지향의 정의 기능이 Open Recursion 이라고 주장합니다 .
Alan Kay에 따르면 OO는 메시징에 관한 것입니다. William Cook에 따르면, OO는 동적 메소드 디스패치 (실제로 동일한 것)에 관한 것입니다. 벤자민 피어스 (Benjamin Pierce)에 따르면, OO는 Open Recursion에 관한 것입니다. 이는 기본적으로 자체 참조가 동적으로 해결되거나 (또는 적어도 생각하는 방식 임), 즉 메시징입니다.
보시다시피, "OO"라는 용어를 만든 사람은 대상에 대해 다소 형이상학 적 관점을 가지고 있고, Cook은 다소 실용적 관점을 가지고 있으며, 매우 엄격한 수학적 관점을 관통합니다. 그러나 중요한 것은 철학자, 실용 주의자 및 이론가가 모두 동의한다는 것입니다! 메시징은 OO의 한 축입니다. 기간.
상속에 대한 언급은 없습니다! OO에는 상속이 반드시 필요한 것은 아닙니다. 일반적으로 대부분의 OO 언어에는 구현 재사용 방법이 있지만 반드시 상속 할 필요는 없습니다. 예를 들어 어떤 형태의 위임 일 수도 있습니다. 실제로, 올랜도 조약은 상속에 대한 대안으로서 위임 을 논의 하고, 다른 형태의 위임과 상속이 어떻게 객체 지향 언어의 디자인 공간 내에서 다른 디자인 포인트로 이어지는 지 논의합니다. (실제로 Java와 같은 상속을 지원하는 언어에서도 사람들은 실제로 그것을 피하도록 지시 받았으며 다시 OO에 필요하지 않음을 나타냅니다.)