2016-11-24 7 views
0

하나의 일반적인 메소드와 하나의 일반적인 메소드가있는 인터페이스가 있습니다. 나는 두 개의 다른 클래스에 대해 일반적인 메소드를 구현했지만, 지금은 일반적인 메소드로 그렇게하는 법은 없다.Java에서 두 클래스에 대해 하나의 일반 메소드를 구현하는 방법

Sphere.java :

public class Sphere implements GeometricShape<Sphere> { 

    private double radius; 

    public Sphere (double radius) { 
     this.radius = radius; 
    } 

    public double volume() { 
     return (4.0/3.0) * Math.PI * radius * radius * radius; 
    } 

    public void describe() { 
     System.out.println("Sphere[radius=" + radius + "]"); 
    } 

    @Override 
    public Sphere supersize() 
    { 
     this.radius*=2; 
     return new Sphere(radius); 
    } 

} 

Rectangle.java

public class Rectangle implements TwoDShape { 

    private double width, height; 

    public Rectangle (double width, double height) { 
     this.width = width; 
     this.height = height; 
    } 

    public double area() 
    { 
     return width * height; 
    } 

    public double perimeter() 
    { 
     return 2.0 * (width + height); 
    } 

    public void describe() 
    { 
     System.out.println("Rectangle[width=" + width + ", height=" + height + "]"); 
    } 

    @Override 
    public Rectangle supersize() 
    { 

     this.width*=2; 
     this.height*=2; 
     return new Rectangle(width, height); 
    } 


} 

TwoDShape.java :

public interface TwoDShape extends GeometricShape 
{ 
    public double area(); 

} 

ThreeDShape.java :

public interface ThreeDShape extends GeometricShape<ThreeDShape> 
{ 
    public double volume(); 
} 
,536 여기 내 코드입니다

GeometricShape.java :

public interface GeometricShape<T extends GeometricShape<T>> 
{ 
    public void describe(); 
    public T supersize(); 

} 

마지막으로 메인 클래스의 ArrayListExample.java :

import java.util.ArrayList; 


public class ArrayListExample { 



    public static void describe_all(ArrayList<? extends GeometricShape> shapes) 

    { 
     for(int i=0;i<shapes.size();i++) 
     { 
      shapes.get(i).describe(); 

     } 
     System.out.println("Total number of shapes:"+ shapes.size()); 
    } 



    public static void main(String[] args) { 


     System.out.println("The describe() method:"); 

     System.out.println(); 
     System.out.println("Example rectangles"); 
     ArrayList<Rectangle> rects = new ArrayList<Rectangle>(); 
     rects.add(new Rectangle(2.0, 3.0)); 
     rects.add(new Rectangle(5.0, 5.0)); 
     describe_all(rects); 
     System.out.println(); 


     ArrayList<Sphere> spheres = new ArrayList<Sphere>(); 
     spheres.add(new Sphere(10.0)); 
     spheres.add(new Sphere(50.0)); 
     spheres.add(new Sphere(0.0)); 

     System.out.println("Example spheres"); 
     describe_all(spheres); 
     System.out.println(); 
     System.out.println("The supersize() method:"); 
     System.out.println(); 

     ArrayList<Rectangle> double_rects = supersize_list(rects); 
     describe_all(double_rects); 
     System.out.println(); 

     ArrayList<Sphere> double_spheres = supersize_list(spheres); 
     describe_all(double_spheres); 

    } 


} 

내가 supersize_list 방법을 구현할 수있는 방법이

같은 두 사각형 및 구 출력에서 ​​초대형 방법을 취
Rectangle[width=4.0, height=6.0] 
Rectangle[width=10.0, height=10.0] 
Total number of shapes: 2 

Sphere[radius=20.0] 
Sphere[radius=100.0] 
Sphere[radius=0.0] 
Total number of shapes: 3 

도와 주시겠습니까? 도와 주셔서 감사합니다.

+0

나는'supersize' 새로운 객체를 반환 이유에 혼란 스러워요을 변환하는 일반적인 방법이 아니라 기존 개체의 크기를 증가해야합니까? –

+1

@ SkaryWombat 동의합니다.하지만 둘 중 하나만 수행해야합니다. –

+0

예, 저는 구형과 사각형 모두에서 크기를 두 배로 늘리고 싶습니다. 당신의 제안은 무엇입니까? 증가 된 크기의 사각형과 구를 반환하는 하나의 supersize_list 메서드를 작성하고 싶습니다. @Scary Wombat @ Luke Lee –

답변

1

충분하다. 예를 들어, 명확한 이유가 없으므로 ThreeDShape extends GeometricShape<ThreeDShape>TwoDShape extends GeometricShape이 동시에 있습니다. 이러한 유형에 대한 일반적인 메소드를 작성하는 것은 재미 있지 않습니다.

덜 혼란스러운 버전입니다. (희망) 주 : 나는 모양 자체의 크기를 supersize 메서드에서 변경하지 않고 원래 모양을 유지하면서 더 큰 모양을 반환하도록 선택합니다.

1 GeometricShape

/** 
* A geometric shape interface. You can do two things with it. 
* 1. Ask it to describe itself (to stdout); 
* 2. Ask it to return a bigger version of itself (double the size). 
*/ 
public interface GeometricShape<T extends GeometricShape<T>> { 
    /** 
    * Print a description to STDOUT 
    */ 
    void describe(); 

    /** 
    * Returns a bigger shape. 
    * @return Something that's a GeometricShape 
    */ 
    T supersize(); 
} 

2 Shape2D 및 직사각형

/** 
* A 2-dimensional shape. 
* It has area. 
* Its supersize() method should return a Shape2D instance. 
*/ 
public interface Shape2D<T extends Shape2D<T>> extends GeometricShape<T> { 

    double area(); 
} 

/** 
* A rectangle. 
*/ 
public final class Rectangle implements Shape2D<Rectangle> { 

    private final double width; 
    private final double height; 

    public Rectangle(double width, double height) { 
     this.width = width; 
     this.height = height; 
    } 

    @Override 
    public String toString() { 
     return "Rectangle{" + 
       "width=" + width + 
       ", height=" + height + 
       '}'; 
    } 

    @Override 
    public void describe() { 
     System.out.println(this); 
    } 

    @Override 
    public Rectangle supersize() { 
     return new Rectangle(width*2, height*2); 
    } 

    @Override 
    public double area() { 
     return width * height; 
    } 
} 

3. Shape3D 및 구

/** 
* A 3-dimensional shape. 
* It has volume. 
* Its supersize() method should return a Shape3D instance. 
*/ 
public interface Shape3D<T extends Shape3D<T>> extends GeometricShape<T> { 

    double volume(); 
} 

/** 
* A sphere 
*/ 
public final class Sphere implements Shape3D<Sphere> { 
    private final double radius; 

    public Sphere(double radius) { 
     this.radius = radius; 
    } 

    @Override 
    public String toString() { 
     return "Sphere{" + 
       "radius=" + radius + 
       '}'; 
    } 

    @Override 
    public void describe() { 
     System.out.println(this); 
    } 

    @Override 
    public Sphere supersize() { 
     return new Sphere(radius*2); 
    } 

    @Override 
    public double volume() { 
     return 4*Math.PI*Math.pow(radius, 3)/3; 
    } 
} 
이제

목록

public static <T extends GeometricShape<T>> 
List<T> supersize_list(List<T> list) { 
    List<T> result = new ArrayList<>(); 
    for (T shape : list) { 
     result.add(shape.supersize()); 
    } 
    return result; 
} 
+0

@Luke Lee의 멋진 설명에 감사드립니다! 그러나 그것은 sphere와 rectangle에 대한 supersize_list와 여전히 일치하지 않는 main에서 supersize_list 메소드 모두에 오류를 보여 주었고 올바르게 실행하려면 앞에 캐스팅해야했습니다. 왜이 에러가 발생했는지 이해할 수 없다. –

+0

결과를'ArrayList'로 캐스팅하고 있습니까? 대신'List'로 선언 해보십시오. 'List double_rect = ...'. –

+0

아니요, 결과를 캐스팅하지 않았습니다. 올바르게 실행하려면 ArrayList double_rects 및 ArrayList double_spheres를 캐스팅했습니다. 이 두 가지를 변경하지 않고 대신 제네릭 방식으로이 작업을 수행 할 수 있습니까? –

0

새 개체를 반환하지 않아도됩니다. 예를 들어 Rectangle를 들어

@Override 
public void supersize() 
{ 

    this.width*=2; 
    this.height*=2; 
} 

는 클래스 계층에 일관성이 보이는

+0

그러면 일반적인 것이 아닙니다. 하지만 나에게 그것은 괜찮아. 이 경우 –

+0

을 사용하면 GeometricShape에서 일반적인 방법으로 supersize를 변경해야합니다. T supersize()를 변경하지 않고 구현하고 싶습니다. –

+0

@LukeLee'supersize'가 구체적인 Object의 필드에서 작동하기 때문에 generics가 필요 없습니다. ** 기하학 **의 supersize도 변경해야합니다 –