Java: когда я создаю экземпляр подкласса абстрактного класса, он не распознает конструктор его суперкласса - PullRequest
0 голосов
/ 03 мая 2011

Я не очень разбираюсь в Java, но я вижу коды, в которых есть абстрактный класс с определенным конструктором, а затем подкласс этого абстрактного класса без конструктора.Затем, когда создается экземпляр подкласса, он создается с помощью конструктора суперкласса.Это верно?

У меня есть этот абстрактный класс:

public abstract class Tile{

    public int x;
    public int y;
    public int z;

    protected Color color;
    protected float friction;
    protected float bounce;
    protected boolean liquid;

    public void Tile(int x, int y, int z){
        this.x = x;
        this.y = y;
        this.z = z;
        init();
    }
    abstract protected void init();

И этот подкласс:

public class TestTile extends Tile{
    protected void init(){
        color = Color.RED;
        friction = 0.1f;
        bounce = 0.2f;
        liquid = false;
    }
}

Но когда я создаю экземпляр TestTile с этим:

Tile tile = new TestTile(0, 0, 0);

метод init () никогда не запускается.Все значения, определенные внутри него, являются нулевыми.Я попытался сделать то, что я, хотя и мог бы быть избыточным конструктором в подклассе, который просто вызывал super с точно такими же параметрами, но когда я сделал это, даже с super (x, y, z) единственным оператором внутри, он сказал следующее:

TestTile.java: 27: вызов super должен быть первым оператором в конструкторе

Я хочу создать группу подклассов Tile, которые реализуют свойства Tile,Если это неправильный способ сделать это, что может быть лучше?

Я использую 32-разрядную версию Ubuntu Linux 11.04, если она связана с чем-либо.

Спасибо.

Ответы [ 4 ]

6 голосов
/ 03 мая 2011

Ваш конструктор не в правильном формате конструктора, это void, сделайте это:

public Tile(int x, int y, int z){
        this.x = x;
        this.y = y;
        this.z = z;
        init();
    }
1 голос
/ 03 мая 2011

Прежде всего, Tile имеет только один конструктор с параметрами x, y, z, без конструктора по умолчанию, поэтому вам нужно вызвать super (x, y, z) в конструкторе TestTile. Как сказал slandau , «конструктор» имеет неправильный void тип возврата.

TestTile необходимо объявить параметры или передать значения по умолчанию:

public TestTile(int x, int y, int z) {
  super(x, y, z);
}

public TestTile() {
  super(0, 0, 0);
}

В Java существует много рисков для вызова абстрактного метода в конструкторе, см. Также здесь , экземпляр не инициализирован должным образом. Вы можете только вызывать безопасные статические методы (которые здесь не будут работать).

public TestTile(int x, int y, int z) {
  super(x, y, z);
  color = Color.RED;
  friction = 0.1f;
  bounce = 0.2f;
  liquid = false;
}

или вам нужно вызвать закрытый метод в производном классе (уберите реферат init() из Tile):

public TestTile(int x, int y, int z) {
  super(x, y, z);
  init();
}

private void init() {
  color = Color.RED;
  friction = 0.1f;
  bounce = 0.2f;
  liquid = false;
}

Вы уверены, что участники - правильная реализация здесь? Может быть, абстрактные методы (геттеры) могут быть здесь лучше объявить поведение и реализовать его в подклассе?

public abstract class Tile {
  public int x;
  public int y;
  public int z;

  public Tile(int x, int y, int z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }

  public abstract Color getColor();
  public abstract float getFriction();
  public abstract float getBounce();
  public abstract boolean isLiquid();
}

public class TestTile extends Tile {

  public TestTile(int x, int y, int z) {
    super(x, y, z);
  }

  public Color getColor() {
    return Color.RED;
  }

  public float getFriction() {
    return 0.1f;
  }

  public float getBounce() {
    return 0.2f;
  }

  public boolean isLiquid() {
    return false;
  }

}
1 голос
/ 03 мая 2011

Я не вижу конструктора для TestTime, который принимает три аргумента.Я вообще не вижу ctor, а это значит, что все, что у вас есть, это значение по умолчанию, которое дает вам компилятор.Я пошел слишком быстро и пропустил это?

Я бы рекомендовал обратить на это особое внимание.Я бы переосмыслил этот дизайн:

Что не так с перезаписываемыми вызовами методов в конструкторах?

Попробуйте это - это включает исправление для вашего конструктора и позволяет избежать проблемы, связанной сдругая нить указывает:

public abstract class Tile{

    public int x;
    public int y;
    public int z;

    protected Color color;
    protected float friction;
    protected float bounce;
    protected boolean liquid;

    public Tile(int x, int y, int z){
        this.x = x;
        this.y = y;
        this.z = z;
    }
}


public class TestTile extends Tile{

    // You're missing this.
    public TestTile(int x, int y, int z)
    {
        super(x, y, z);
        this.init();
    }

    protected void init(){
        color = Color.RED;
        friction = 0.1f;
        bounce = 0.2f;
        liquid = false;
    }
}
0 голосов
/ 03 мая 2011

Конструкторы не наследуются, поэтому трехпараметрический конструктор Tile не вызывается при создании объекта TestTile.Вам нужно явно вызвать трехпараметрический конструктор Tile из конструктора TestTile, как вы и сказали, что пытались, но этот вызов super (x, x, x) должен быть первым оператором конструктора TestTile.

И, как сказал Мэтт Болл, ваш «конструктор» Tile на самом деле не является конструктором, пока вы не удалите возвращаемый тип void.

...