누가 인터페이스를 확장합니까? 그리고 왜?


20

AFAIK, 클래스 extends부모 클래스 및 implements인터페이스. 그러나 나는 사용할 수없는 상황을 뛰어 넘습니다 implements SomeInterface. 제네릭 형식의 선언입니다. 예를 들면 다음과 같습니다.

public interface CallsForGrow {...}

public class GrowingArrayList <T implements CallsForGrow>  // BAD, won't work!
                              extends ArrayList<T> 

여기서 사용하는 implements것은 구문 상 금지되어 있습니다. 먼저 <> 내부의 인터페이스를 사용하는 것은 금지되어 있다고 생각했습니다. 가능하지만 extends대신 대신 사용해야 합니다 implements. 결과적으로 인터페이스를 "확장"합니다. 이 다른 예는 다음과 같습니다.

public interface CallsForGrow {...}

public class GrowingArrayList <T extends CallsForGrow>  // this works!
                              extends ArrayList<T> 

나에게 그것은 구문상의 불일치로 보인다. 그러나 아마도 Java 6의 훌륭한 점을 이해하지 못합니까? 인터페이스를 확장해야 할 다른 장소가 있습니까? 확장하려는 인터페이스에 특별한 기능이 있어야합니까?

답변:


25

제네릭 형식 변수의 경우 컴파일러는 T클래스, 인터페이스, 열거 형 또는 주석 인지 실제로 신경 쓰지 않습니다 . 관심있는 것은 그것이 주어진 하위 유형과 수퍼 유형이있는 유형이라는 것입니다.

그리고 실제로 인터페이스를 구현하는 다른 장소에서 클래스와 인터페이스의 구별이 관련이 있기 때문에 구문을 복잡하게 할 이유가 없습니다 (예 implement: 인터페이스의 경우 정의하는 모든 메소드를 구현해야하지만 extend(추상적이지 않은 수업 인 경우) 필요하지 않습니다 .

implements여기서 작성해야 할 순간을 가정하면 enum값을 작성하는 대신 값을 작성 <E extends Enum<E>>하고 주석을 사용하여 쉽게 선언 할 수 있는 별도의 구문도 필요합니다 <A extends Annotation>.

작성 해야 할 유일한 곳 implements은 실제로 인터페이스를 구현하는 지점입니다. 에서 점 (그리고 점 만 있음)이 인터페이스에 정의 된 메소드를 구현해야하기 때문에 차이가 중요하다. 다른 모든 사람들에게 주어진 A클래스가 기본 클래스 또는 구현 된 인터페이스 인지 여부는 중요하지 않습니다 B. 그것은 슈퍼 타입이며 그게 전부입니다.

또한 extends인터페이스와 함께 사용 하는 다른 장소가 있습니다 .

interface A {
}

interface B extends A {
}

이 시점 에서는 구현하지 않기implements 때문에 잘못되었습니다 .B A


논리를 사용하려면 제네릭뿐만 아니라 'extends SomeInterface'를 항상 사용해야합니다 .
Gangnus 2019

2
@ Gangnus : 아니요. 구현 자extends 와의 사이에 구체적인 차이점이 있기 때문에 implements순수한 유형 시스템 관점에서 문제를 볼 때 차이가 없다는 것입니다.
Joachim Sauer

1
죄송합니다, 당신의 생각을 이해하지 못합니다. --1. "순수한 유형 시스템 관점"을 사용해야하는 이유는 무엇입니까? --2. 구문이 다른 장소에서 왜 변화를 요구합니까? 설명해 주시겠습니까? 가능하다면 대답하십시오.
강 누스

1
@ 강 누스 : 누가 T클래스 라고 말하는가 ? T인터페이스 유형 또는 유형을 참조 할 수 enum있습니다.
Joachim Sauer

1
C #에서 나온이 모든 토론은 말도 안됩니다. 로 타입의 수퍼 타입을 나타냅니다 :. 표지 아래에서 인터페이스는 abstract다중 상속을 허용하기 위해 구현되지 않은 가상 ( ) 멤버 만 포함해야하는 제한 사항이있는 추상 클래스이며 항상 추상 클래스입니다 . 사이에 차이 문자가 없다 implements하고 extends. 그것들은 같은 단어 ( extends) 또는 임의의 기호 ( :) 로 대체 될 수 있으며 아무것도 잃어 버리지 않습니다.
sara

5

Java 5, 특히 제네릭이 관심을 등록한 개발자가 처음 사용할 수있게되었을 때 구문은 매우 달랐습니다. 대신 Set<? extends Foo>Set<? super Bar>그것을 가지고 Set<+Foo>Set<-Foo>. 그러나 피드백은 더 구체적 인지 또는 더 넓은 지 (더 많은 클래스)를+ 의미 하는지 명확하지 않다는 의견이었습니다 . Sun은 구문을 변경하여 피드백에 응답했지만 새로운 키워드를 도입하지 않아야한다는 제약 조건 내에서 이전 버전과의 호환성에 문제가있었습니다.

그 결과 어느 것도 자연스럽지 않습니다. 아시다시피, extends다른 컨텍스트에서 사용되는 언어가 아닌 클래스 "확장"인터페이스에 대해 오버로드됩니다. 및 super이전 수퍼 참조 키워드, 즉,로 표시되는 관계가 반대 방향 인 "의 수퍼 클래스가 인"의미 과부하.

그러나 인터페이스의 기본 사항은이 변경의 영향을받지 않으며 새로운 방식으로 확장되는 특수 인터페이스를 도입하지 않습니다.


+1. 보고 동의합니다. 그러나 Joachim Sauer는 T가 반드시 클래스라는 잘못된 생각을 발견했습니다. 그래서 대답은 그의 것입니다. 당신의 이해는 1 층 (또는 2 층)입니다 :-). 내 문제는 더 원시적이었다. 어쨌든 내 개발에 감사드립니다.
Gangnus

2

이러한 구문을 허용하고 금지하는 데는 단점이 있으며, 허용하는 것이 훨씬 더 크다.

그냥 생각 해봐

인터페이스와 구현의 분리 기본적인 프로그래밍 관용구 중 하나입니다. 이 때문에 "인터페이스가 무언가를 구현합니다"라는 철자를 허용하는 구문 은 피연산자의 곱셈 을 나타 내기 위해 더하기 기호를 사용하는 것만 큼 나쁩니다 .


승인. 그래서 나는 정말로 무언가를 이해하지 못합니다. 나는 그것을 매우 가능성이 있다고 생각했다. 그러나 당신은 문제를 전혀 설명하지 않았습니다. 죄송합니다. T는 클래스를 나타냅니다. 한 곳에서 T 확장을 사용하고 다른 곳에서 T 구현을 사용하는 이유는 무엇입니까?
Gangnus

제공 한 예에서 @Gangnus는 T가 반드시 클래스가 아닌 타입 파라미터 를 . Joachim이 이미 말한 것을보십시오 . 구현 을 허용하면 내가 언급 한 것과 같은 혼란이 생길 ​​것입니다.
gnat

예, 나는 이미 그의 의견을 보았습니다. 답변을하면 답변으로 표시됩니다. 내 감사와 +1이있을 때까지.
Gangnus

-1

인터페이스 를 이해 하면서 다음 단계로 인터페이스 중심 프로그래밍 을 이해해야합니다. 인터페이스의 실제 사용이 무엇인지 알려줍니다. Java (또는 다른 언어) 프로그램에서 어떤 역할을합니까?


2
귀하의 답변은 OP의 문제를 어떻게 해결합니까? 부디 편집 더 명확로 답변을.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.