2013-03-21 2 views
3

가정하면 다음과 같은 클래스 정의됩니다형 T 매개 변수는

public static <T extends Shape> void draw(T shape) { } // 2 

자바 컴파일러는 모양과 T를 대체

class Shape { } 
class Circle extends Shape { } 
class Rectangle extends Shape { } // 1 

당신은 다른 모양을 그리는 일반적인 방법을 쓸 수 있습니다 :

public static void draw(Shape shape) { } // 3 

내 질문에 우리 클래스에서 직접 3을 정의하면 우리는 여전히 o // 3의 메소드에 대한 Shape, CircleRectangle 참조. 그렇다면 우리는 타입 매개 변수 <T extends Shape>을 가진 // 2 generic 메쏘드를 쓸 필요가 있습니다. 이것은 분명히 // 3과 같을 것입니다.

당신은 같은 예제이 링크를 참조 할 수 있습니다 : http://docs.oracle.com/javase/tutorial/java/generics/genMethods.html

+3

당신은 할 수 없을 것입니다. 기본적으로 나쁜 예가됩니다. –

+0

// 메소드를 수행 할 필요가 없습니다. 2. 실제 상속의 목적 중 하나는 상속 된 객체의 많은 "모양"을 전달하는 것이므로 // 메소드를 수행하는 것이 더 좋습니다. 그래서이 경우 // 3이 더 합리적입니다. –

답변

6

당신이 필요로하거나하지 않을 수도 있습니다. 우리가하지 않기 때문에, 충분하지 않을 것 Shape을 전달 위

public static <T extends Shape> void drawWithShadow(T shape, Class<T> shapeClass) { 
    // The shadow must be the same shape as what's passed in 
    T shadow = shapeClass.newInstance(); 
    // Set the shadow's properties to from the shape... 
    shadow.draw(); // First, draw the shadow 
    shape.draw(); // Now draw the shape on top of it 
} 

: 당신의 방법은 예를 들어, 정확하게 T extends Shape의 유형과 일치해야합니다 유형 T의 다른 개체를 처리하는 경우 필요 똑같은 유형의 그림자를 만들 수 있습니다.

이러한 요구 사항이없는 경우 간단한 Shape이면 충분합니다.

2

을이 특정한 경우에, 당신은 일반적인 방법이 필요하지 않습니다.

그러나 일반적인 방법을 사용하면 인수에 동적으로 연결된 메서드를 호출하는 것보다 더 많은 작업을 수행 할 수 있습니다.

예를 들어 T 요소 컬렉션을 허용하고 반환하는 일반 메서드가있을 수 있습니다. 유형별로 매개 변수화하면 여러 콜렉션 유형에 사용할 수 있습니다.

일반적인 방법이 유용한 다른 예는 Java tutorial입니다.

1

코드의 다른 부분에서 특정 유형의 모양으로 메서드의 사용을 제한 할 수 있다는 점이 가장 큰 장점입니다. 어떤 점에서

에서 런타임에, 당신은 유형 Shape

2

의 무언가를 전달합니다 심지어 경우에만 Rectangle 및 다른 장소에만 Circle이 컴파일시에 확인됩니다에 그릴을 변수화 할 수 있습니다 당신의 예를 들어, // 3은 실제로 // 2와 동일합니다. 그러나 다른 쓰임새에, 제네릭 형식 유용 할 수 있습니다 :

  • 당신이 인수로 같은 유형, 방법에서 값을 반환 할

  • 당신은 2 개 이상의 매개 변수를 가지고 제한을 설정하려면 그들은 같은 유형이어야합니다.

1

차이점은 사용하고있는 다형성의 종류입니다.두 번째 당신이 하위에 의해 다형성을 사용하는 동안 당신이 파라 메트릭 다형성을 사용하는 일반적인 경우

. 실제로 첫 번째 경우는 두 가지 종류의 다형성을 사용합니다.

이제는 일부 측면에서 유사 할 수 있지만 동일하지는 않습니다. 실제적인 예 :

List<Shape> shapes; 
List<T extends Shape> specificShapes; 
당신은 그 첫 번째 경우에, 유형 매개 변수를 가지고 있지, 난 모양의 특정 하위 유형의 목록을 관리 할 수 ​​없습니다 볼 수 있습니다

, 난 단지 모양의 eterogeneous 목록을 관리 할 수 ​​있지만, 나는 그것에 특정한 어떤 것도 강요 할 수 없다. 그래서 나는 TriangleRectangleshapes에 추가하는 것을 금지하는 컴파일 타임 주스를 가지고 있지 않습니다.

class ShapeDecorator { 
    private Shape shape; 

    .. 

    Shape get() { return shape; } 
} 

class ShapeDecorator<T extends Shape> { 
    private T shape; 

    T get() { return shape; } 
} 

또 다른 예가 있습니다.이 경우에는 캐스트를 사용하지 않고 유형 T를 반환 할 수있는 일반 데코레이터를 작성할 수 있습니다. 이것은 하위 유형으로서 공통 조상을 갖는 것이 충분하지 않은 많은 상황에서 유용 할 수 있습니다.