Java 에서 유형 매개 변수의 경계를 정의 extends
하기 위해 항상 " "대신 " " 를 사용하는 특별한 이유가 있는지 궁금합니다 implements
.
예:
public interface C {}
public class A<B implements C>{}
금지되어 있지만
public class A<B extends C>{}
맞다. 그 이유는 무엇입니까?
implements
추가했습니다. 도움이 되길 바랍니다.
Java 에서 유형 매개 변수의 경계를 정의 extends
하기 위해 항상 " "대신 " " 를 사용하는 특별한 이유가 있는지 궁금합니다 implements
.
예:
public interface C {}
public class A<B implements C>{}
금지되어 있지만
public class A<B extends C>{}
맞다. 그 이유는 무엇입니까?
implements
추가했습니다. 도움이 되길 바랍니다.
답변:
클래스 '구현'또는 '확장'사이에는 일반 제약 조건 언어에서 의미 상 차이가 없습니다. 제한 가능성은 'extends'와 'super'입니다. 즉,이 클래스는 다른 클래스 (extends)에 할당 가능하게 작동하거나이 클래스가 해당 클래스 (super)에서 지정할 수 있습니다.
class Generic<RenderableT extends Renderable implements Draggable, Droppable, ...> { Generic(RenderableT toDrag) { x = (Draggable)toDrag; } }
One은 컴파일 타임 검사를 원합니다.
대답은 다음과 같습니다 .
경계 형식 매개 변수를 선언하려면 형식 매개 변수 이름,
extends
키워드, 상한 […]을 차례로 나열하십시오 . 이 문맥에서 extends는 일반적인 의미로extends
(클래스에서와 같이) 또는implements
(인터페이스에서와 같이 ) 의미로 사용됩니다 .
그래서 당신은 그것을 가지고 있고, 약간 혼란스럽고 오라클은 그것을 알고 있습니다.
getFoo(List<? super Foo> fooList)
문자 그대로 Foo와 같이 확장 된 클래스에서만 작동합니다 class Foo extends WildcardClass
. 이 경우 a List<WildcardClass>
는 허용 가능한 입력입니다. 그러나 Foo
구현 하는 클래스가 작동 class Foo implements NonWorkingWildcardClass
하지 않는다고해서 해당 클래스가 List<NonWorkingWildcardClass>
유효 하지는 않습니다 getFoo(List<? super Foo> fooList)
. 맑은!
아마도 양쪽 (B와 C)의 경우 구현이 아닌 유형 만 관련이 있기 때문입니다. 당신의 예에서
public class A<B extends C>{}
B도 인터페이스가 될 수 있습니다. "extends"는 하위 인터페이스뿐만 아니라 하위 인터페이스를 정의하는 데 사용됩니다.
interface IntfSub extends IntfSuper {}
class ClzSub extends ClzSuper {}
나는 보통 '으로'하위 슈퍼를 확장 '생각 서브가 같다 슈퍼 하지만, 추가 기능과 함께'및 'CLZ 구현 Intf에' '로 CLZ이 의 실현 Intf에 '. 귀하의 예에서 이는 다음과 일치합니다. B 는 C 와 같지만 추가 기능이 있습니다. 기능은 실현이 아니라 여기에 관련됩니다.
기본 유형은 일반 매개 변수 일 수 있으므로 실제 유형은 클래스의 인터페이스 일 수 있습니다. 치다:
class MyGen<T, U extends T> {
또한 클라이언트 코드 관점에서 인터페이스는 클래스와 거의 구별 할 수 없지만 하위 유형의 경우 인터페이스가 중요합니다.
사용하는 용어 중 임의의 종류입니다. 어느 쪽이든 될 수 있습니다. 아마도 언어 설계자들은 "확장자"를 가장 기본적인 용어로, "구현물"을 인터페이스의 특별한 경우라고 생각했을 것입니다.
그러나 나는 implements
조금 더 의미가 있다고 생각 합니다. 나는 통신하는 더 많은 매개 변수 유형은 상속 관계에 있어야 할 필요가 없습니다, 그들이 될 수 있다고 생각 어떤 서브 타입 관계의 종류.
Java 용어집도 비슷한 견해를 나타 냅니다.
우리는 익숙해
class ClassTypeA implements InterfaceTypeA {}
class ClassTypeB extends ClassTypeA {}
이 규칙에서 약간 벗어난 것은 우리를 크게 혼란스럽게합니다.
유형 경계의 구문은 다음과 같이 정의됩니다.
TypeBound:
extends TypeVariable
extends ClassOrInterfaceType {AdditionalBound}
( JLS 12> 4.4. 타입 변수>TypeBound
)
변경해야한다면 반드시 implements
사례를 추가해야합니다
TypeBound:
extends TypeVariable
extends ClassType {AdditionalBound}
implements InterfaceType {AdditionalBound}
두 개의 동일하게 처리 된 조항으로 끝납니다
ClassOrInterfaceType:
ClassType
InterfaceType
( JLS 12> 4.3. 참조 유형 및 값>ClassOrInterfaceType
)
우리가 돌봐 줄 필요가 있다는 점만 빼면 implements
더 복잡해집니다.
나는 그것이 주된 이유하다고 생각 extends ClassOrInterfaceType
대신에 사용 extends ClassType
하고 implements InterfaceType
복잡한 개념 내에서 일을 간단하게 유지하기 위해 -. 문제는 우리 모두를 커버 할 수있는 권리 단어가없는 것입니다 extends
그리고 implements
우리는 확실히 하나를 소개하고 싶지 않아요.
<T is ClassTypeA>
<T is InterfaceTypeA>
하지만 extends
이 인터페이스와 함께 갈 때 약간의 혼란을 제공합니다, 그것은 광범위한 용어입니다 두 가지 경우를 설명하는 데 사용 할 수 있습니다. 유형 을 확장하는 개념 ( 인터페이스를 구현 하지 않고 클래스를 확장 하지 않음) 에 맞춰 마음을 조정하십시오 . 다른 유형 으로 유형 매개 변수를 제한하면 해당 유형이 실제로 무엇인지는 중요하지 않습니다. 상한 과 수퍼 타입 이라는 것만 중요합니다 .
실제로 인터페이스에서 generic을 사용하면 키워드도 확장됩니다 . 코드 예제는 다음과 같습니다.
인사말 인터페이스를 구현하는 두 가지 클래스가 있습니다.
interface Greeting {
void sayHello();
}
class Dog implements Greeting {
@Override
public void sayHello() {
System.out.println("Greeting from Dog: Hello ");
}
}
class Cat implements Greeting {
@Override
public void sayHello() {
System.out.println("Greeting from Cat: Hello ");
}
}
그리고 테스트 코드 :
@Test
public void testGeneric() {
Collection<? extends Greeting> animals;
List<Dog> dogs = Arrays.asList(new Dog(), new Dog(), new Dog());
List<Cat> cats = Arrays.asList(new Cat(), new Cat(), new Cat());
animals = dogs;
for(Greeting g: animals) g.sayHello();
animals = cats;
for(Greeting g: animals) g.sayHello();
}
implements
?" - ""만 있기 때문입니다extends
.