C ++ 및 Java의 추상 클래스 / 인터페이스에 대한 다른 사용 근거가 있습니까?


13

Herb Sutter에 따르면 구현을 가능한 한 분리하기 위해 C ++의 클래스를 추상화하는 추상 인터페이스 (모든 순수 가상 함수)를 선호해야합니다. 개인적으로이 규칙이 매우 유용하다고 생각하지만 최근에는 많은 Java 프로그래머와 함께 팀에 합류했으며 Java 코드에는이 지침이 존재하지 않는 것 같습니다. 함수와 그 구현은 종종 추상 클래스에 있습니다. 그래서 C ++에서도 Herb Sutter가 잘못 되었습니까? 아니면 C ++에서 Java와 비교하여 추상 함수의 사용법에 일반적인 차이가 있습니까? 구현 코드가있는 추상 클래스가 C ++보다 Java에서 더 현명합니까? 그렇다면 왜 그럴까요?


1
Java oo에 대해 누락 된 일부 디자인 원칙으로 인해 몇 가지 의심이 있었고 마침내 여기에 넣었습니다. 따라서 일반적인 조언에 관한 것이 아니라 언어를 사용하는 옳고 그름에 대한 자세한 내용입니다
Martin

인터페이스는 순수 가상입니다. 추상 클래스의 개념은 그것들이 부분적으로 구현된다는 것이며, 불필요하게 코드를 반복하지 않고 간격을 메우는 것은 구현에 달려 있습니다 (예를 들어, 모든 서브 클래스에서 write (int)의 abstract class call write (byte)

1
아마도 관련이 있습니다 : stackoverflow.com/q/1231985/484230 는 Java의 추상 클래스를 선호하는 이유를 제공합니다. C ++의 경우, 인터페이스 레벨에서 기능을 추가 할 수있는 무료 기능이 존재하기 때문에이 이유는 사실이 아닌 것 같습니다
Martin

1
골든 규칙은 "리프가 아닌 클래스를 추상화"하는 것이지만 "순수한"또는 "빈"요구 사항은 아닙니다.
Kerrek SB

1
그것이 당신을 위해 작동한다면 그것은 당신을 위해 작동합니다. 사람들이 일단 코드가 더 이상 최신 의견을 고수하지 않는 이유를 알 수 없습니다.
James

답변:


5

OOP는 구성과 치환이 있습니다.

C ++에는 다중 상속, 템플릿 전문화, 임베딩 및 가치 / 이동 / 포인터 시맨틱이 있습니다.

Java에는 단일 상속 및 인터페이스, 임베드 및 참조 시맨틱이 있습니다.

OOP 학교에서 이러한 언어를 사용하는 일반적인 방법은 객체 대체 및 컴포지션을위한 상속을 사용하는 것입니다. 그러나 공통 조상과 런타임 캐스트 방법이 필요합니다 (C ++에서는 dynamic_cast, Java에서는 다른 인터페이스를 요구합니다).

자바는이 모든 것을 독자적인 java.lang.Object뿌리 계층 구조로 수행합니다. C ++에는 사전 정의 된 공통 루트가 없으므로 최소한 동일한 "그림"이되도록 정의해야합니다 (그러나 이것은 일부 C ++ 가능성을 제한하고 있습니다 ...).

그 후, 컴파일 타임 다형성 (CRTP로 생각) 및 가치 의미론을 가질 가능성은 "OOP 객체"개념을 C ++ 프로그램으로 이식 할 수있는 방법에 대한 다른 대안을 제공 할 수 있습니다.

당신은 실제로 전통적인 학교 패러다임을 뒤집는 구성을 관리하기 위해 대체 및 개인 상속을 관리하기 위해 포함 및 암시 적 변환을 사용하는 이단을 상상할 수 있습니다. (물론이 방법은 다른 방법보다 20 년 어리기 때문에 그렇게하는 데 폭 넓은 커뮤니티 지원을 기대하지 마십시오)

또는 "다중 스택을 통해 인터페이스에서 구현으로 디스패치 할 때"우세 "를 사용하여 부분적으로 구현 된 인터페이스에서 균일 한 인터페이스 클러스터를 거치는 인터페이스 (구현 없음)에서 최종 클래스 (완전하게 구현 됨)까지 모든 클래스에 대한 가상 공통 기반을 상상할 수 있습니다. -평행도 "상속 체계.

OOP 방식이 단 하나 뿐이고 OOP 방식 만 있다고 가정하면 OOP와 Java를 C ++과 비교하는 것은 두 언어의 기능을 모두 제한하는 것입니다.

C ++가 Java 코딩 관용구를 엄격하게 준수하도록 강요하는 것은 Java가 C ++와 유사한 언어로 작동하도록하는 것이 Java를 변질시키는 것이므로 C ++를 변질시키는 것입니다.

"민감성"의 문제가 아니라 다른 "집계 메커니즘"의 문제로, 두 언어가 다른 언어보다 한 언어에서 일부 관용구를 다른 언어보다 더 수익성있게 만드는 두 언어가 서로 다른 방식으로 결합합니다.


1
이 답변은 언어 기능을 교리가 아닌 도움으로 만 OO 및 디자인 원칙을위한 도구로 간결하게 설명하기 때문에 매우 흥미 롭습니다. 그러나 C ++에서 oo를 수행하려면 공통 루트가 필요하지 않습니다. 이것은 또한 운영자와 템플릿이 있다는 사실에도 불구하고 잘못되었습니다 (이것은 지적한 자바의 기본 트리 디자인에 대한 매우 강력한 대안입니다). 그 외에도 당신의 요점은 모든 답에서 가장 가치가 있습니다
Martin

1
@Martin : "기술적 인 의미"당신이 맞아요,에서하지만 (인스턴스화 된 객체의 실제 타입이 프로그램 입력에 의존하기 때문에) 당신이 polymorophism 런타임 필요하다면 "루트"( 'A'는 것입니다 기사,하지에 대한 바로 가기 " 단 하나만 ") 모든 개체를"사촌 "으로 만들고 계층을 실행 가능하게합니다. 다른 뿌리는 서로 관련되지 않은 다른 조상 에서 유래 합니다. 이것이 "좋은"것인지 "나쁜"것인지는 관용구가 아니라 맥락의 문제입니다.
Emilio Garavaglia

사실입니다. 나는 당신이 전체 c ++ 프로그램에 대한 하나의 일반 루트를 인위적으로 제공하는 것을 언급하고 있다고 생각하고 그것이 java와 비교하여 그것이 존재하지 않는 결함으로 보았습니다. 그러나 편집 후에는 요점을 명확하게 알 수 있습니다. 다시 한번 감사드립니다
Martin

12

이 원칙은 두 언어 모두에 적용되지만 공정한 비교는하지 않습니다. C ++ 순수 추상 클래스를 Java 인터페이스와 비교해야합니다.

C ++에서도 일부 함수가 구현 된 추상 클래스를 가질 수 있지만 순수한 추상 클래스 (구현 없음)에서 파생됩니다. Java에서는 인터페이스 (구현 없음)에서 파생 될 수있는 동일한 추상 클래스 (일부 구현)가 있습니다.


따라서 C ++의 인터페이스 클래스보다 추상 클래스를 선호하는 경우는 언제입니까? 저는 항상 C ++에서 인터페이스와 비 멤버 함수를 선택했습니다.
Martin

1
디자인에 따라 @Martin 기본적으로 항상 인터페이스를 선호합니다. 그러나 " 항상 "규칙은 ... 예외가
Luchian 고르

사실이지만 Java 코드에서는 대다수를 대표하는 추상 클래스가 보입니다. 인터페이스에서 작동하는 무료 함수가 Java에서 불가능하다는 사실 때문일 수 있습니까?
Martin

3
@Martin 잘 무료 기능은 Java에서 전혀 가능하지 않으므로 이유가 될 수 있습니다. 좋은 자리! 자신의 질문에 대답했습니다! 당신은 스스로 대답을 추가 할 수 있습니다.
Luchian Grigore

4

일반적으로 동일한 OO 원칙이 Java 및 C ++에 적용됩니다. 그러나 한 가지 큰 차이점은 C ++은 다중 상속을 지원하지만 Java에서는 하나의 클래스에서만 상속 할 수 있다는 것입니다. 이것이 Java가 내가 믿는 인터페이스를 가지고있는 주된 이유입니다. 여러 상속의 부족을 보완하고 아마도 당신이 할 수있는 것을 제한해야합니다 (여러 상속의 남용에 대해 많은 비판이 있기 때문에). 따라서 Java 프로그래머에게는 아마도 추상 클래스와 인터페이스 사이에 더 큰 차이점 이 있습니다. 추상 클래스는 동작을 공유하고 상속하는 데 사용되는 반면 인터페이스는 단순히 추가 기능을 추가하는 데 사용됩니다. Java에서는 하나의 클래스에서만 상속 할 수 있지만 많은 인터페이스를 가질 수 있습니다. 그러나 C ++에서 순수한 추상 클래스 (예 : "C ++ 인터페이스") Java 인터페이스의 목적과 달리 동작을 공유하고 상속하는 데 사용됩니다 (여전히 함수를 구현해야하지만) 사용법은 Java 인터페이스와 다릅니다.


0

때로는 기본 구현을하는 것이 합리적입니다. 예를 들어 모든 하위 클래스에 적용 가능한 일반 PrintError (string msg) 메소드입니다.

virtual PrintError(string msg) { cout << msg; }

실제로 필요한 경우 여전히 재정의 할 수 있지만 클라이언트가 일반 버전을 호출하도록하여 번거 로움을 덜 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.