1

For a project in Java I want to create a private reference to an array in a superclass, but do not implement it. I want to do the implementation in the childclass, so I created a getter method for that array in the superclass. In the childclasses constructor, I implement the array and now the problem is, that the array reference in the superclass stays null even if I added an array to the reference. I want to use the array later in the superclass. I will add some code for better understanding.

I understand my fault that this is not easily possible in Java like this, but is there any solution to "edit" the array like this by it's reference or do I have to do this with a setter method?

//parent class
public abstract class Superclass {
    private Test[] test_Values;
    
    public Measurement[] getTestValues() {
        return this.test_Values;
    }
}

//child class
public class ChildClass extends SuperClass {

    public ChildClass() {
        Test[] measures = super.getTestValues();
        measures = new Test[4];
    }
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Theodor H
  • 13
  • 4
  • 1
    You would be better off creating a `setter` method `setTestValues(...)` – Scary Wombat Sep 08 '21 at 08:24
  • Why not simply do the initialization of the array in the parent constructor? You'd need to call that constructor in all of your child classes – QBrute Sep 08 '21 at 08:24
  • 1
    Does this answer your question? [Is Java "pass-by-reference" or "pass-by-value"?](https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) – Izruo Sep 08 '21 at 08:24
  • `Test[] measures = super.getTestValues();` - java is not C++ – Scary Wombat Sep 08 '21 at 08:24
  • Thank you for your current answers. I have different child classes with differnet array sizes so i want to implement it with the currently needed array size in the child class. – Theodor H Sep 08 '21 at 08:28
  • `measures = new Test[4];` is setting a local variable, not the field whose value is returned by a method. – Andy Turner Sep 08 '21 at 08:30
  • "so i want to implement it with the currently needed array size in the child class" pass an int to the constructor of `Superclass` to indicate the size of the array. – Andy Turner Sep 08 '21 at 08:32

1 Answers1

0

Initialize your array in the parent constructor:

public abstract class Superclass {
    private Test[] test_Values;

    protected Superclass(int capacity) {
        this.test_Values = new Test[capacity];
    }

    public Test[] getTestValues() {
        return this.test_Values;
    }
}

Then, you have to use that non-default constructor in your child classes.

public class ChildClass extends SuperClass {

    public ChildClass() {
        super(4);
    }
}

Or, to get additional control over how you initialize the values in the array, you could add an abstract method that is used in the parent's constructor:

public abstract class Superclass {
    private Test[] test_Values;

    protected Superclass() {
        this.test_Values = initializeArray();
    }

    public Test[] getTestValues() {
        return this.test_Values;
    }

    protected abstract Test[] initializeArray();
}

The child class then needs to implement that abstract method:

public class ChildClass extends SuperClass {
    @Override
    protected Test[] initializeArray() {
        Test[] testValues = new Test[4];
        // calculate elements
        return testValues;
}
QBrute
  • 4,405
  • 6
  • 34
  • 40
  • "you could add an abstract method that is used in the parent's constructor" no, [that is a bad approach](https://stackoverflow.com/questions/3404301/whats-wrong-with-overridable-method-calls-in-constructors). You shouldn't call overrideable ("alien") methods from a constructor. If you want to specify elements in the subclass, pass in the pre-filled array as the constructor parameter. – Andy Turner Sep 08 '21 at 08:33
  • @AndyTurner why not? What do you mean by "alien" methods? – QBrute Sep 08 '21 at 08:35
  • The problems with this approach are described in detail in the question I linked. – Andy Turner Sep 08 '21 at 08:36
  • Okay, this constructor approach should work pretty well. Thank you! – Theodor H Sep 08 '21 at 08:43
  • @AndyTurner Ah, didn't see the link at first. But if you want to pass in the pre-filled array as parameter (with additional initialization logic), you'd need a helper method anyway to be able to pass it to `super`. I've read the linked question, but I disagree with how the accepted answer generalizes things: *If you violate this rule, program failure will result*. This doesn't need to be the case if you know how the code behaves. In the particular example I've given, you only supply a fresh array without depending on the state of the yet unfinished object. – QBrute Sep 08 '21 at 08:43