Treehee
Treehee

Reputation: 127

How do I use a subclass' static fields in superclass' method when calling via instance of subclass?

I have a model class, with a subclass called square. In the model class I have a draw method, that needs some fields from the subclass. I have an instance of the subclass and want to call its draw function (which is not to be overridden in the subclass).

I'm trying to make something using openGL on Android, and have alot of models that use essentially the same code to draw, but use different meshes, thus have different fields. I think it's a bit redundant to copy the draw function to every single model class, and when I try to simply add empty fields on the model class and fields of the same name on the subclass, it uses the fields from the superclass when calling the method using an instance of the subclass, also, passing the fields as parameters is not an option, since the super constructor call has to be the first call in the subclass' constructor, and I need to apply some operations to the fields in the subclass' constructor (I think, I'm not experienced with OOP as you can tell).

Alot of the following is temporary as I am still trying to get the hang of things

stripped down model superclass:

abstract public class Model {
    static final int COORDS_PER_VERTEX = 3;
    final float Coords[];
    public Model(){
        //do some stuff unrelated to the issue
        }
    public void draw(){
        final int vertexCount = Coords.length / COORDS_PER_VERTEX;
        }
    }

stripped down model subclass:

public class Square extends Model{
    private static float Coords[] = {
                -0.5f, 0.5f, 0.0f,   // top left
                -0.5f, -0.5f, 0.0f,   // bottom left
                0.5f, -0.5f, 0.0f,   // bottom right
                0.5f,  0.5f, 0.0f }; // top right
    public Square() {
        super();
        //do something to Coords
        }
    }

method call:

private ArrayList<Model> models = new ArrayList<>();
models.add(new Square());
for (Model model:models) {
        model.draw();
    }

I expect the draw function to use to value 12/3=4 for vertexCount, but instead it raises a NullPointer error, because you can't use .length on a null Array.

Upvotes: 0

Views: 48

Answers (2)

Bor Laze
Bor Laze

Reputation: 2506

Because inheritance is not applied to fields. You code should looks like

abstract public class Model {
    static final int COORDS_PER_VERTEX = 3;
    public Model(){
        //do some stuff unrelated to the issue
    }
    public void draw(){
        final int vertexCount = getCoords().length / COORDS_PER_VERTEX;
    }
    abstract public float[] getCoords();
}

public class Square extends Model {
    private static float Coords[] = {
                -0.5f, 0.5f, 0.0f,   // top left
                -0.5f, -0.5f, 0.0f,   // bottom left
                0.5f, -0.5f, 0.0f,   // bottom right
                0.5f,  0.5f, 0.0f }; // top right
    public Square() {
        super();
        //do something to Coords
    }

    public float[] getCoords() {
        return Coords;
    }
}

or

abstract public class Model {
    static final int COORDS_PER_VERTEX = 3;
    protected float coords[];

    public Model(float[] coords){
        this.coords = coords;

        //do some stuff unrelated to the issue
    }
    public void draw(){
        final int vertexCount = coords.length / COORDS_PER_VERTEX;
    }
}

public class Square extends Model {
    public Square(){
        super(new float[] {
            -0.5f, 0.5f, 0.0f, 
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f, 
            0.5f,  0.5f, 0.0f }
        );
    }
}

Upvotes: 1

Eran
Eran

Reputation: 393801

You could write a getter method that returns the Coords array. This way each sub-class can override it to return a different variable.

abstract public class Model
{

    protected float[] getCoords() {
        return Coords;
    }

}

public class Square extends Model {

    @Override
    protected float[] getCoords() {
        return Coords;
    }

}

I know it doesn't make much sense to return a static instance variable in an instance method, but you can only override instance methods.

Upvotes: 0

Related Questions