Home > OS >  Inherited Static Variables
Inherited Static Variables

Time:03-23

I'm trying to implement a simple chess problem with inheritance, but i found myself stuck.

I have my abstract Chesspiece class and many child classes for each type of piece. I need an array to store the possible moves of each piece, so i was thinking about making the variable static because this array is always the same and independent from the instance

public class Knight extends Chesspiece{
    public static final int dy = {1, 1, 2, 2, -1, -1, -2, -2}; 
    public static final int dx = {2, -2, 1, -1, 2, -2, 1, -1}; 
}

Somewhat like this, but afterwards in my logic I only have instances without knowing its subtype, so i cant access this variables.

I thought maybe i could somehow declare an abstract variable or something in my Chesspiece class, and then overwrite its value in each subclass. But after searching i found out that java doesn't let static inheritance.

So im wondering what would be the best solution to this problem. I'm very keen on learing good conceptual programming so each time i write better code. I have though solutions that work (not making the variables static), but they don't seem right or elegant for this problem. Any help is appreciated.

CodePudding user response:

I thought maybe i could somehow declare an abstract variable or something in my Chesspiece class, and then overwrite its value in each subclass. But after searching i found out that java doesn't let static inheritance.

There are a couple things to correct in here:

  • Firstly, you can't have abstract variables (by which I assume you mean fields). Fields don't participate in inheritance, so they can't be declared in one class, and then "implemented" in another.
  • Secondly, static and abstract don't go together. They are completely separate things. So, this statement is a non-sequitur.

The correct way to do this is to add abstract methods to a base class or interface. For example, assuming your Chesspiece class is abstract, add it there:

abstract class Chesspiece {
  // ...

  abstract int[] getDx();
  abstract int[] getDy();

  // ...
}

Now, non-abstract classes that extend Chesspiece have to provide implementations:

class Knight extends Chesspiece{
    private static final int dy = {1, 1, 2, 2, -1, -1, -2, -2}; 
    private static final int dx = {2, -2, 1, -1, 2, -2, 1, -1}; 

    @Override int[] getDy() { return dy; }
    @Override int[] getDx() { return dx; }
}

If you do it like this, the same array instances are returned each time. This is not necessarily desirable, however, because it allows the internal state of the Knight instances to be changed:

Knight robin = new Knight();
System.out.println(robin.getDx()[0]); // 2

Knight galahad = new Knight();
galahad.getDx()[0] = 42;

System.out.println(galahad.getDx()[0]); // 42.
System.out.println(robin.getDx()[0]); // 42 !?

To get around this, don't return the same instance each time: either declare the array inside the getter:

    @Override int[] getDx() {
      return new int[] {2, -2, 1, -1, 2, -2, 1, -1};
    }
Knight robin = new Knight();
System.out.println(robin.getDx()[0]); // 2

Knight galahad = new Knight();
galahad.getDx()[0] = 42;

System.out.println(galahad.getDx()[0]); // 2
System.out.println(robin.getDx()[0]); // 2

Alternatively, copy the array in the getter:

    @Override int[] getDx() {
      return Arrays.copyOf(dx, dx.length);
    }
  • Related