【问题标题】:Inherit subclass variable by super in JavaJava中通过super继承子类变量
【发布时间】:2016-07-28 07:30:34
【问题描述】:

这个标题没有很好地表达我的意思,我很抱歉,但我很难更好地表达它,因为由于缺乏 OOP 知识和经验,我不太明白发生了什么。

我正在构建一个基本游戏,让玩家在一个带有“英雄”精灵的棋盘上跑来跑去,被一个“坏人”精灵追逐。因为这两个精灵共享 5-6 个方法,所以我决定制作一个超类“Sprite”和两个类“Hero extends Sprite”和“BadGuy extends Sprite”。现在对于所有这些超级方法,包括以下内容:

getX(); getY(); getBounds(); render();

为了工作,我需要超级类来跟踪“Hero”和“badGuy”的位置。所以我像这样实现了'Sprite':

package game.sprites;

import javafx.scene.shape.Rectangle;

import javax.swing.*;
import java.awt.*;

public class Sprite {

    public static int x;
    public static int y;
    private int imageWidth;
    private int imageHeight;
    public Image image;

    public Sprite(int x, int y) {
        Sprite.x = x;
        Sprite.y = y;
    }

    public static void render(Graphics g, Image image) {
        g.drawImage(image, x, y, null);
    }

    public Image loadImage(String filePath) {...}

    public void getImageDimensions() {...}

    public Rectangle getBounds() {
        return new Rectangle(x, y, imageWidth, imageHeight);
    }

    public Image getImage() {
        return image;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}

当我想为“Hero”和“BadGuy”对象提供不同的起始坐标时,问题就出现了。目前,如果我将它们设置为不同,“Sprite”的第二次调用会覆盖第一次调用,并且两者都从同一位置开始(如果您的目标是从“badGuy”运行,这将非常令人沮丧)。 'Hero' 和 'BadGuy' 目前是这样初始化的:

public class BadGuy extends Sprite {

    public BadGuy() {
        super(x, y);
        initBadGuy();
    }

    public void initBadGuy() {
        loadImage("resources/craft.gif");
        getImageDimensions();
        x = 860; // Hero x = 20;
        y = 560; // Hero y = 20;
    }

所以我试图做的是让子类覆盖 Sprite 的 x 和 y。但是我用谷歌搜索了它,我知道这是一个非常糟糕的主意,因此这是不可能的。所以我的问题是这样的:如何让'Sprite'继承子类'x'和'y'变量并在调用某个子类时执行必要的方法。

现在我看一下 - 构造函数和 init() 对于子类是相同的,所以也许它们可以在“Sprite”中实现?只是一个想法,但我已经很困惑了,所以不知道。

谢谢。

【问题讨论】:

  • 只需将构造函数 Hero(int x, int y) 和 BadGuy(int x, int y) 添加到调用 super(x,y) 的子类中。
  • 这是因为你在 sprite STATIC 中做了 x 和 y 变量。这意味着任何更改变量的子类都会导致在所有其他子类中看到该更改。只要让它们受到保护,子类就可以应付了
  • 不要创建xy 变量static。它们应该是类的实例变量。他们应该跟踪每个Sprite 对象。您还应该考虑将Sprite 类设为abstract

标签: java oop inheritance subclass superclass


【解决方案1】:

您遇到此问题是因为 xy 在您的 Sprite 类中被声明为静态字段。
来自JLS 8.3.1.1. static Fields

如果一个字段被声明为静态,那么无论最终创建多少个类的实例(可能为零),都只存在该字段的一个化身。静态字段,有时称为类变量,在类初始化时体现(第 12.4 节)。

使用以下代码:

如下改变你的 Sprite 类:

public class Sprite {

    public int x;
    public int y;
    ....
}

BadGuy 类:

public class BadGuy extends Sprite {
    public BadGuy(int x, int y) {
       super(x, y);
        ...
    }
  ....
}

英雄职业:

public class Hero extends Sprite {
    public Hero(int x, int y) {
       super(x, y);
        ...
    }
  ....
}

从主类执行以下操作://从您要创建两个类的对象的位置

public static void main(String[] args){
 Hero hero = new Hero(20,20);
 BadGuy badGuy= new BadGuy(860,560);
}

【讨论】:

  • 另外,请注意在问题的上下文中使用static
  • @SumitSingh 感谢您抽出宝贵时间详细解释。还有一件事(这样我可以更好地理解事物):我可以在子类中分配起始坐标,而不是将它们作为参数传递给每个子类的构造函数,当它被调用时。因为他们将在每场比赛中从同一个地点开始,所以将这些起始坐标封装在类中是有意义的。或者至少对我来说是有意义的:D
猜你喜欢
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-06
相关资源
最近更新 更多