【问题标题】:How to implement one generic method for two classes in java如何在java中为两个类实现一个泛型方法
【发布时间】:2016-11-24 00:31:17
【问题描述】:

我有一个接口,它有一个普通方法和一个通用方法。我已经为两个不同的类实现了普通方法,但现在不知道如何用泛型方法做到这一点。这是我的代码:

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);
    }

}

矩形.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();
}

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 方法,它从矩形和球体中获取 supersize 方法并输出类似

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

你能帮我解决这个问题吗?非常感谢您的帮助!

【问题讨论】:

  • 我很困惑为什么supersize会返回一个新的对象,不应该只是增加现有对象的大小吗?
  • @ScaryWombat 我同意,它应该做任何一个,但不能同时做。
  • 是的,我想将球体和矩形的大小增加两倍。你有什么建议?我想编写一个 supersize_list 方法,它返回大小增加的矩形和球体@Scary Wombat @Luke Lee
  • @user_01 这不是我们所困惑的。
  • 是的,也许我不应该返回一个新对象,但我不知道如何使用一个 supersize_list 方法返回新的大小。请写下你的方法好吗?

标签: java generics inheritance interface generic-method


【解决方案1】:

类层次结构看起来不一致。例如,您同时拥有ThreeDShape extends GeometricShape&lt;ThreeDShape&gt;TwoDShape extends GeometricShape,没有明显的原因。为这些类型编写泛型方法并不好玩。

这是一个不太容易混淆的版本。 (希望)注意:我在supersize方法中选择不改变形状本身的大小,而是让它在保持原来不变的情况下返回更大的形状。

1.几何形状

/**
 * 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;
}

【讨论】:

  • 感谢@Luke Lee 的精彩解释!但是,它在 main 中的 supersize_list 方法中都显示错误,因此仍然与球体和矩形的 supersize_list 不匹配,并且需要在它们前面强制转换才能正确运行。我不明白为什么会出现这个错误
  • 您要将结果投射到ArrayList 吗?尝试将它们声明为 ListList&lt;Rectangle&gt; double_rect = ....
  • 不,我没有转换结果,我转换了 ArrayList double_rects 和 ArrayList double_spheres 以便正确运行。我的意思是不改变这两个,我怎么能在泛型方法中做到这一点?
  • 'ArrayList double_rects = supersize_list(rects);描述_所有(双直); System.out.println(); System.out.println("超大球体列表"); ArrayList double_spheres = supersize_list(spheres);描述_所有(双球体);'在两个 supersize_list 前面都显示错误
  • 那你必须做ArrayList&lt;Rectangle&gt; double_rects = (ArrayList&lt;Rectangle&gt;)supersize_list(rects); 才能让它工作?将其更改为List&lt;Rectangle&gt; double_rects = supersize_list(rects);
【解决方案2】:

您不需要返回新对象。以Rectangle 为例

@Override
public void supersize() 
{

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

足够了

【讨论】:

  • 那么它不会是通用的。但对我来说这很好。
  • 在这种情况下,我应该将 supersize 更改为 GeometricShape 中的普通方法。我想实现 T supersize() 而不改变它
  • @LukeLee supersize 作用于具体对象的字段,不涉及泛型。 几何中的超大尺寸也应该改变
  • 我的意思是如何在不改变 GeometricShape 的情况下实现该通用方法
  • 你的GeometricShape 不需要任何泛型
猜你喜欢
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
相关资源
最近更新 更多