EJS
EJS

Reputation: 1071

Should I keep field initialization in the declaration of a superclass when subclasses initialize in the constructor?

Based on the answers from this question, given that I have a class with fields initialized on the declaration, what should I do when I extend that class and need the subclass to have a different default value?

Should I assign the new default value in the constructor of the subclass and keep the assignment in the declaration for the superclass?:

public class Bird {
    private boolean flight = true;
}

public class Penguin extends Bird {
    public Penguin() {
        flight = false;
    }
}

Or should I refactor so that both classes initialize fields in the constructor?

From the answers in this question it looks like there are no significant technical differences, so this is a question about semantics.

Upvotes: 2

Views: 77

Answers (2)

Joop Eggen
Joop Eggen

Reputation: 109547

First the differences between the two cases.

For an immutable property (the most restrictive - nice - case):

public class Bird {
    public final boolean flight;

    public Bird() {
        this(true);
    }

    protected Bird(boolean flight) {
        this.flight = flight();
    }
}

public class Penguin extends Bird {
    public Penguin() {
        super(false);
    }
}

For a more liberal, dynamic usage:

public class Bird {
    protected boolean flight = true;
    public boolean hasFligth() {
        return flight;
    }
}

public class Penguin extends Bird {
    public Penguin() {
        flight = false;
    }
}

However flight might be considered not a property on every individual Bird / Penguin object: it is a property of the class (Penguin, Ostrich, ...). A kind of strategy pattern, or:

Map<Class<Bird>, Boolean>
Set<Class<Bird>> // better

Situated at the other side, in a class Flight.

Upvotes: 2

lexicore
lexicore

Reputation: 43661

If you design your superclass for extension and want to allow certain field to be initializable to another value, you should probably expose this via constructor parameter:

public class Bird {
    private final boolean flight = true;
    public Bird() {
        this(true);
    }
    public Bird(boolean flight) {
        this.fligjt = flight;
    }
    public boolean isFlight() {
        return this.flight;
    }
}

public class Penguin extends Bird {
    public Penguin() {
        super(false);
    }
}

Upvotes: 1

Related Questions