0

所以我有一个对象的 ArrayList。这些对象内部是各种属性及其值。

代码非常简单。GBox 和 GCircle 是 GHP 的子代。ArrayList 在 World 中。

我要做的是打印盒子的HP和体积以及圆圈的HP和直径。我知道我可以覆盖toString(),但我实际上想获取这些值。这样做的正确语法是什么?

//Main.java
public class Main {
    public static void main(String[] args) {
        Ini i = new Ini();
    }
}

//Ini.java
public class Ini {
    private static World w;

    public Ini() {
        w = new World;
        w.makeGBox();
        w.makeGCircle();
        System.out.println("Box: HP: " +
                           w.getList().get(0).getHP() +
                           "Volume: " +
                           w.getList().get(0).GBox.getVolume());
                           //compile error no variable GBox in GHP
        System.out.println("Circle: HP: " +
                           w.getList().get(1).getHP() +
                           "Radius: " +
                           w.getList().get(1).GCircle.getRadius());
                           //compile error no variable GCircle in GHP
    }
}

//World.java
import java.util.ArrayList;

public class World {
    private ArrayList<GHP> list = new ArrayList<>();

    public void makeGBox() {
        list.add(new GBox());
    }
    public void makeGCircle() {
        list.add(new GCircle());
    }

    public ArrayList<GHP> getList() {
        return list;
    }
}

//GHP.java
public class GHP {
    private int HP;

    public GHP() {
        setHP(5);
    }

    public int getHP() {
        return HP;
    }
    public void setHP(int HP) {
        this.HP = HP;
    }
}

//GBox.java
public class GBox extends GHP{
    private int volume;

    public GBox() {
        setVolume(10);
    }

    public int getVolume() {
        return volume;
    }
    public void setVolume(int volume) {
        this.volume = volume;
    }
}

//GCircle.java
public class GCircle extends GHP{
    private int radius;

    public GCircle {
        setRadius(7);
    }

    public int getRadius() {
        return radius;
    }
    public void setRadius(int radius) {
        this.radius = radius;
    }
}
4

5 回答 5

1

除了许多编译问题之外,您还需要这些更改来实现您想要的。

for (GHP ghp : w.getList()) { // Avoid using get(index) without a forloop, as such
    if (ghp instanceof GBox) { // Using the instanceof operator, you can differentiate the 2 class types
        System.out.println("Box: HP: " + ghp.getHP() + "Volume: "
                + ((GBox) ghp).getVolume()); // Cast it to GBox to be able to call getVolume
    }

    if (ghp instanceof GCircle) {
        System.out.println("Circle: HP: " + ghp.getHP() + "Radius: "
                + ((GCircle) ghp).getRadius());// Cast it to GCircle to be able to call getRadius 
    }
}
于 2013-10-04T07:59:10.843 回答
0

您需要将通用GHP引用转换为特定类型,例如:

((GCircle) ghp).getRadius()

您可能还想看看instanceof操作员。

这个想法是:

  • 对于输出,您覆盖该toString()方法,因为您不需要任何特定于类的信息,只需打印出对象详细信息

  • 对于特定于类的操作,您向下转换为特定类型

于 2013-10-04T07:52:32.140 回答
0

当您读取列表值时,编译器唯一知道的是列表包含GHP实例。

首先检查类型,然后将其强制转换为子类。

GHP ghp = w.getList().get(0);
if(ghp instanceof GBox) {
  GBox gbox = (GBox) ghp;
  // Here you can access the method getVolume()
  /* ... */  gbox.getVolume();
}
于 2013-10-04T07:53:14.020 回答
0

向基类和/或instanceof检查添加方法的更简洁、更 OOP 的替代方法是使用访问者模式,该模式允许您将对象结构与对其进行操作的任何算法分开。这种情况下的算法只是一个“显示”算法。

也就是说,对于大多数简单的情况(例如这种情况),将方法添加到基类并覆盖或使用instanceof都很好。

于 2013-10-04T07:58:20.817 回答
0
List<Shape> shapes = new ArrayList<Shape>();    

…………

for (Shape shape : shapes) {
            System.out.println(shape.getHp());
            if(shape instanceof Circle){
                System.out.println(((Circle) shape).getValuem());
            }else if(shape instanceof Box){
                System.out.println(((Box) shape).getHieght());
        }

试试这个方法。。

于 2013-10-04T08:22:49.660 回答