0

我正在创建一个游戏。当我扩展我的 Block 类时,它显示一个错误。

错误:隐式超级构造函数 Block() 未定义。必须显式调用另一个构造函数

代码:

游戏.java:

package lt.projecturanium;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import java.util.HashMap;

import javax.swing.JFrame;

import lt.projecturanium.blocks.Block;
import lt.projecturanium.blocks.BlockRectangle;
import lt.projecturanium.entity.Player;
@SuppressWarnings("unused")

public class Game extends Canvas implements Runnable{

    private static final long serialVersionUID = 1L;

    private static JFrame _frame;
    public static Game _instance;

    private static final String TITLE = "Project Uranium";
    private static final int WIDTH = 650;
    private static final int HEIGHT = WIDTH * 3 / 4;

    private static final int UPDATE_RATE = 50;
    private static final int RENDER_RATE = 100;

    public static HashMap<Block, Coordinates> blocks = new HashMap<Block, Coordinates>();

    public int rectx = 0;
    public int recty = 0;
    public int rectID = 0;

    public boolean hitted = false;

    public float interpolation;

    public static final Dimension SIZE = new Dimension(WIDTH, HEIGHT);

    private Thread _thread;

    private boolean _running;

    private int _totalTicks = 0;
    private int _tps = 0;
    private int _fps = 0;

    public Game()
    {
        _instance = this;
        setPreferredSize(SIZE);
        setMinimumSize(SIZE);
        setMaximumSize(SIZE);

        _frame = new JFrame(TITLE);

        _frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        _frame.setLayout(new BorderLayout());
        _frame.add(_instance, BorderLayout.CENTER);
        _frame.pack();

        _frame.setResizable(false);
        _frame.setLocationRelativeTo(null);
        _frame.setVisible(true);
        createBufferStrategy(2);
        blocks.put(new Block(new BlockRectangle(200)), new Coordinates(30, 50));
    }
    public synchronized void start()
    {
        _running = true;
        _thread = new Thread(this, TITLE+"_main");
        _thread.start();
    }
    public synchronized void stop()
    {
        _running = false;
        if (_thread != null)
        {
            try {
                _thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public void paint(Graphics g) {
        super.paint(g);  // fixes the immediate problem.
        Graphics2D g2 = (Graphics2D) g;
        g2.drawString("FPS: " + _fps + "\n TPS: " + _tps, 10, 10);
        if (hitted)
        {
            recty = 0;
            rectx += 21;
            rectID++;
            blocks.put(new Block(new BlockRectangle(rectID)), new Coordinates(rectx, recty));
            hitted = false;
        }
        recty++;
        g2.drawImage(Player.getTexture(), 60, 60, null);
        g2.drawRect(rectx, recty, 20, 20);
        g2.setColor(new Color(101, 67, 33));
        g2.fillRect(0, 430, getWidth(), getHeight());
        g2.setColor(new Color(0, 100, 0));
        g2.fillRect(0, 420, getWidth(), 10);
        g2.setColor(Color.BLACK);
        if (recty == (419 - 20))
        {   
            hitted = true;
        }
    }
    public void run() {
        double lastUpdateTime = System.nanoTime();
        double lastRenderTime = lastUpdateTime;
        final int ns = 1000000000;
        final double nsPerUpdate = (double) ns / UPDATE_RATE;
        final double nsPerRender = (double) ns / RENDER_RATE;
        final int maxUpdatesBeforeRender = 5;

        int lastSecond = (int) (lastUpdateTime / ns);
        int tickCount = 0;
        int renderCount = 0;
        while (_running) {

          long currTime = System.nanoTime();
          int tps = 0;

          while ((currTime - lastUpdateTime) > nsPerUpdate && tps < maxUpdatesBeforeRender) {
            update();
            tickCount++;
            _totalTicks++;
            tps++;
            lastUpdateTime += nsPerUpdate;
            interpolation = Math.min(1.0F, (float) ((currTime - lastUpdateTime) / nsPerUpdate));
            render(interpolation, getGraphics());
          }

          if (currTime - lastUpdateTime > nsPerUpdate) {
            lastUpdateTime = currTime - nsPerUpdate;
          }
          if (currTime - lastRenderTime == maxUpdatesBeforeRender + 1)
          {
              render(interpolation, getGraphics());
          }
          renderCount++;
          lastRenderTime = currTime;

          int currSecond = (int) (lastUpdateTime / ns);
          if (currSecond > lastSecond) {
            _tps = tickCount;
            _fps = renderCount;
            tickCount = 0;
            renderCount = 0;
            lastSecond = currSecond;
            _frame.setTitle(TITLE + " | TPS: " + _tps + " | FPS: "+ _fps);

          }

          while (currTime - lastRenderTime < nsPerRender && currTime - lastUpdateTime < nsPerUpdate) {
            Thread.yield();
            try {
              Thread.sleep(1);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
            currTime = System.nanoTime();
          }
        }   
      }
    public void update()
    {
        _frame.pack();
    }
    public void render(float interp, Graphics g)
    {
        BufferStrategy myStrategy = getBufferStrategy(); 
        Graphics gra = myStrategy.getDrawGraphics();
        paint(gra);
        g.dispose();
        myStrategy.show();
        //System.out.println("Grass x: " + blocks.get("grass").getX() + " y: " + blocks.get("grass").getY());
        System.out.println("Stone x: " + blocks.get(new Block(new BlockRectangle(rectID))).getX() + " y: " + blocks.get(new Block(new BlockRectangle(rectID))).getY());
    }
}

块.java:

package lt.projecturanium.blocks;

public class Block {
    private Block block;
    public Block (Block block){
        this.block = this;
    }
    public Block getBlock() {
        return block;
    }
    public Block getBlockById(int id)
    {
        return block;
    }
}

块矩形.java:

package lt.projecturanium.blocks;

import java.awt.Image;
import java.io.IOException;
import java.util.HashMap;

import javax.imageio.ImageIO;

import lt.projecturanium.Game;

public class BlockRectangle extends Block{
    private int id;
    private static HashMap<Integer, BlockRectangle> rects = new HashMap<Integer, BlockRectangle>();
    public BlockRectangle(int id)
    {
        this.id = id;
    }
    public int getID()
    {
        return this.id;
    }
    public static BlockRectangle getByID(int id)
    {
        return rects.get(id);
    }
    public static Image getTexture()
    {
        try{        
            return ImageIO.read(Game._instance.getClass().getClassLoader().getResource("../res/player.png"));   
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        return null;
    }
}

坐标.java:

package lt.projecturanium;

public class Coordinates {
    private int x;
    private int y;
    public Coordinates(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    public int getX()
    {
        return this.x;
    }
    public int getY()
    {
        return this.y;
    }
}
4

6 回答 6

1
public class BlockRectangle extends Block

BlockRectangle扩展了Block。所以在BlockRectangle的构造函数中,首先必须通过super()调用Block的构造函数。

public BlockRectangle(int id){
    //This line is optional if Block has an empty constructor.
    super([...]);
    this.id = id;
}

如果Block有一个空的构造函数,它就会被隐式调用。事实并非如此。因此,您必须自己显式调用super()(或定义一个空的构造函数)。

注意:如果Block根本没有构造函数,则会隐式创建一个空构造函数。

于 2013-09-16T12:24:37.150 回答
0

BlockRectangle(...) needs to call super(null) because the implicit (=not written in code) super() (Block()) does not exist.

于 2013-09-16T12:25:18.030 回答
0

Default constructor only exists if you haven't defined any other constructor for the class. Constructors of subclassess silently call super() if no other constructor is called manually, which means they attempt to call a default constructor.

You can solve this problem by creating a parameterless constructor in Block class yourself or by calling the existing constructor through super in each of the subclasses.

于 2013-09-16T12:26:29.313 回答
0

您收到此错误是因为构造函数

public BlockRectangle(int id)
    {
        this.id = id;
    }

隐式调用super应该是无参数的构造函数Block(){}

由于您为类明确定义了构造函数,编译器不会提供默认的无参数构造函数。所以你应该手动创建它。

Block(){}向您的类添加一个无参数构造函数Block,它将解决您的问题。

于 2013-09-16T12:23:11.527 回答
0

由于您定义了构造函数,Java 不再提供默认构造函数。因此,您必须自己定义一个空构造函数:

public Block()
{
}

另外,我不确定您为什么要保留 aBlock对自身的引用。鉴于您在Block类上拥有的方法,看起来您可能想了解更多关于继承的信息。我认为你在滥用它。

于 2013-09-16T12:22:02.373 回答
0

只要您没有显式定义另一个 Java 类,它就有一个隐式的默认构造函数。这就是你在Block课堂上所做的。

现在,如果您有一个带有构造函数的子类,则隐式调用超类的默认构造函数。

public BlockRectangle(int id)
{
    // Tries to call super() implictly which doesn't exist anymore
    this.id = id;
}

您可以通过在超类中显式定义一个额外的默认构造函数来解决此问题

public Block()
{
}

或通过显式调用非默认超类构造函数

public BlockRectangle(int id)
{
    super(new Block());
    this.id = id;
}

至于另一个话题:你的构造函数Block真的没有任何意义:

public Block (Block block){
    this.block = this;
}

您忽略了参数并将您的字段设置为this. 这是没有意义的,因为this无论如何在类中引用总是可用的。

于 2013-09-16T12:28:32.743 回答