初始化子类中的超类变量(构造函数中需要)

Ka *_*Mai 5 java inheritance constructor subclass superclass

我正在编写一个简单的小行星克隆游戏,Swing用于显示图形.我有点关注Derek Banas的教程,但决定自己扩展.

最初的想法是游戏中的每个图形元素(即小行星,宇宙飞船和子弹)都在扩展这个Polygon类.他们的构造函数看起来像这样:

public class SpaceShip extends Polygon {

    //x and y coordinates
    public static int[] polyXArray = {...};
    public static int[] polyYArray = {...};

    //other class variables
    {...}

    public SpaceShip() {

        super(polyXArray, polyYArray, polyXArray.length);
    }
}
Run Code Online (Sandbox Code Playgroud)

它与其他图形元素类似.

编辑:这里的关键元素是两个数组不存储对象的实际坐标,而是它们相对于中心的位置,其坐标是double-type class-variable.因此,数组只描述对象的形状,而子类move()方法将影响中心的坐标.负责实际绘图的类将调用该move()方法,然后应用仿射变换来移动和旋转形状(根据正确定义的角度参数).我这样做是为了避免与处理double算术有关的精度问题.

现在,因为元素共享了许多"相等"的变量(它们的中心坐标,我需要它们才能用仿射变换,它们的速度分量等来转换它们)和方法(getter和setter,move()方法等等). ..)我想让它们成为抽象类的扩展 - 比方说,GameShape- 它包含所有这些常用的方法和变量.GameShape现在将是Polygon直接扩展的那个:

public abstract class GameShape extends Polygon {

        //x and y coordinates, still unassigned
        public static int[] polyXArray, polyYArray;

        //other class variables
        {...}

        public GameShape() {

            super(polyXArray, polyYArray, polyXArray.length);
        }
}
Run Code Online (Sandbox Code Playgroud)

然后,我想要分配所需的值polyXArray,polyYArray当我定义不同的子类,以绘制我需要的不同形状,但我还没有找到一种方法来做到这一点.

我确实希望这些变量是静态的,因为它们是单个类的特定属性,并且我不希望每次实例化一个新对象时都将它们作为参数传递.

我的情况与此问题中描述的情况非常相似,但提出的解决方案似乎不起作用,因为我需要构造函数中的那些变量.有没有办法克服 - 或周围 - 这个问题?无论程序如何,我的主要目标是为所有图形元素提供一个共同的超类,以避免数十行复制粘贴代码.

Kel*_*dos -1

编辑:

正如 VGR 在评论中所说,这不会编译。因此,我们必须稍微改变一下实现,即我们将使用 HAVE 关系而不是 IS 关系:-)

首先,不要将 Poly 数组字段设为静态。如果这样做,它们对于所有子类也将是相同的,那么有什么意义呢?

其次,这里使用模板方法设计模式。你的类看起来像这样:

public abstract class GameShape {

        //x and y coordinates, still unassigned
        public int[] polyXArray, polyYArray;

        private Polygon polygon;

        //other class variables
        {...}

        public GameShape() {
            instantiatePolyArrays();
            this.polygon = new Polygon(polyXArray, polyYArray, polyXArray.length);
        }

        protected abstract void instantiatePolyArrays();

        public final Polygon getPolygon(){
            return this.polygon;
        }
}
Run Code Online (Sandbox Code Playgroud)

每个扩展类都必须重写此方法,并且您可以在每个方法重写中实例化每个类的数组。

另外,关于 IS-HAVE 关系问题的一句话 - 您在示例中呈现的是 IS 关系,其中对象GameShape是 a Polygon,因此需要调用超级构造函数以及与之相关的问题。在我的解决方案中,这被 HAVE 关系取代,其中GameShape对象内部有一个Polygon对象,可以通过 getPolygon() 方法访问。这使您拥有更多额外的灵活性:-)

  • 那不会编译。对“super(...)”的调用必须是构造函数中的第一个语句。 (3认同)