【问题标题】:java and inheritance constructorsjava和继承构造函数
【发布时间】:2020-08-07 02:53:09
【问题描述】:

我有一个名为 Item 的类通过以下方式完成

public class Item {


private static int nextId = 0;
private double xCoord, yCoord; //location
private double length, height; // define size of item
private String spriteImage;
private Tank tank;
private String id;


protected Item(double xCoord, double yCoord, String spriteImage, double length, double height,  Tank tank) throws ItemException {
    setId("I"+nextId); 
    nextId++;   
    setLocation(xCoord,yCoord);
    setSpriteImage(spriteImage);        
    setLength(length);
    setHeight(height);      
    setTank(tank);
}


/**
 * Set this item's location.
 * 
 * @param xCoord the column coordinate.
 * @param yCoord the row coordinate.
 */
public void setLocation(double xCoord, double yCoord) {
    this.xCoord = xCoord;
    this.yCoord = yCoord;
}

public double getXCoord() {
    return xCoord;
}

public double getYCoord() {
    return yCoord;
}

public double getLength() {
    return length;
}

public void setLength(double length) throws ItemException{
    if(length<=0) {
        throw new ItemException("MSG_ERR_LENGTH_VALUE");
    }
    this.length = length;
}

public double getHeight() {
    return height;
}

public void setHeight(double height) throws ItemException{
    if(height<=0) {
        throw new ItemException("MSG_ERR_HEIGHT_VALUE");
    }
    this.height = height;
}

public void setSpriteImage(String spriteImage) {

    this.spriteImage = spriteImage;
}

public String getSpriteImage() {        
    return spriteImage;
}

public String getId() {
    return id;
}

protected void setId(String id) {
    this.id = id;
}

public Tank getTank() {
    return tank;
}

public void setTank(Tank tank){
    if(tank!=null) {
        if(!tank.getItems().contains(this)) {
                tank.getItems().add(this);
        }
    }

    if(this.tank!=null) {
        try{
            this.tank.removeItem(this);
        }catch(Exception e) {
            //removeItem: El item no existe ya en el tanque
        }
    }

    this.tank = tank;
}


@Override
public String toString() {
    StringBuilder str = new StringBuilder("(" + getXCoord() +",  "+ getYCoord() +") ");

    str.append(getId() + " ");
    str.append(getLength() + " ");
    str.append(getHeight() + " ");
    str.append((getTank()!=null)?getTank().getName():"No tank");
    return str.toString();
}
}

我的问题是我必须实现两个类,其中一个继承自 Items,他们问我:这个类只有一个构造函数,它将与 参数。这些的顺序是:xCoord、yCoord、length、 高度,能量和坦克。 spriteImage 的值将始终是 相同:“./images/food/seed.png” 我实现如下

public class Food extends Item {

double speed=1;
boolean eaten;
int energy;


protected Food(double xCoord, double yCoord, String spriteImage,  double length, double height,int energy, Tank tank)
        throws Exception {
    super(xCoord, yCoord, spriteImage, length, height, tank);   
    setSpeed(speed);
    setEnergy(energy);
    setSpriteImage("./images/food/seed.png");
}

另一个类是一样的,他们问我这个类将有一个构造函数并且将是 带参数,其顺序为:xCoord, yCoord, 长度,高度和坦克。 spriteImage 的值将始终是 相同:“./images/submarine/submarine.png”

public class SubmarineToys extends Item{


double speed=1;
boolean facingRight=true;
double thresholdReverse=0.0003;

protected SubmarineToys(double xCoord, double yCoord, String spriteImage, double length, double height, Tank tank)
        throws ItemException {
    super(xCoord, yCoord, spriteImage, length, height, tank);
    setSpriteImage("./images/submarine/submarine.png");     
}

我的问题是我无法让构造函数在两个类中都要求我只拥有告诉我的参数。

根据超类的不同,构造函数总是在 Super() 中为我创建来自 Item 的参数,但他们要求我只有他们要求的参数,这意味着从超类的构造函数。

某种方式?

项目类不能是抽象的吗?

【问题讨论】:

  • 孩子们的演员抛出两种不同的异常类型有什么原因吗?
  • 关于异常,他们这样问我尝试不同类型的异常,没有更多的理由,我问自己同样的问题。
  • “项目类不能是抽象的吗?” - 取决于。如果您的模型/设计中的Item 应该被用作基类,它可以 被用作基类,并且永远不会被直接实例化。
  • 他们确切地告诉我,任何时候都不会创建任何项目对象但这会解决我与构建者的问题吗?我敢肯定它一定是抽象的。
  • 你可以把它抽象化。不过,我认为这不会解决任何问题。但是如果它被建模为抽象类,那么是的,它应该是抽象的。

标签: java constructor abstract-class extends


【解决方案1】:

您可以简单地从孩子的 ctors 中省略 spriteImage。 结果应该是这样的:

public class Food extends Item {
   private static String foodSpriteImage = "./images/food/seed.png";
   private double speed=1;
   private boolean eaten;
   private int energy;

   // Child Ctor needs to be public.
   public Food(double xCoord, 
                  double yCoord, 
                  double length, 
                  double height,
                  int energy, 
                  Tank tank)
        throws Exception {
       super(xCoord, yCoord, foodSpriteImage , length, height, tank);   
       setEnergy(energy);
   }
}

【讨论】:

  • 我刚刚尝试了你告诉我的,它给了我错误:线程“main”中的异常 java.lang.Error:未解决的编译问题:构造函数 Food (int, int, String, int, int , int, Tank) 未定义删除“spriteImage”参数给我一个超级错误(...)
  • 公开 Food ctor,请参阅我的编辑。并且不要将精灵传递给它。新签名是Food(double, double, double, double, int, Tank)
  • ok!这是一个非常好的解决问题的方法!我没想到!
  • 请注意,您也可以“硬编码”字符串。我的示例故意不是为了表明该字符串也可以来自其他地方。它也可以来自资源文件或“常量”单例,从服务中获取......
【解决方案2】:

您也可以忽略 spriteImage 参数并使用常量字符串调用 super()

protected Food(double xCoord, double yCoord, String spriteImage, double length, double height, int energy, Tank tank) throws Exception {
    super(xCoord, yCoord, "./images/food/seed.png", length, height, tank);
    //                         ↑ here we put our default value instead of the spriteImage parameter
    setSpeed(speed);
    setEnergy(energy);
}

然后我们可能会删除spriteImage-参数:

protected Food(double xCoord, double yCoord, double length, double height, int energy, Tank tank) {...}

【讨论】:

  • 毫无疑问,这是另一种非常正确的方法。
猜你喜欢
  • 2013-03-21
  • 2011-09-09
  • 2010-12-11
  • 1970-01-01
  • 2012-10-09
  • 1970-01-01
  • 2014-11-22
相关资源
最近更新 更多