Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use an abstract method or an instance variable for data that should be specified by sub-class?

I am writing an abstract class and I have a variable that should be defined by the sub-class (in this case it is an int which is used in the super-class). I can't decide whether to define a protected variable with a default value and let the sub-class change the value either in the constructor or through a setter method. Or to define an abstract method in the parent class such that all sub-classes must implement it and return the value they want to be used (then access the method in the super-class using the abstract method). Can anyone tell me if there are any great reasons why one way should be preferred over the other?

Abstract Method:

public abstract int getValue();

public int getValue() {
    return 5;
}
  • Pros:

Forces sub-class to think about this value and choose what they want it to be.

  • Cons:

No default value, so even if most of the sub-classes just want to use the same value they still have to implement the method. (The method can be made non-abstract and return the default value, but then you lose the advantage of forcing sub-classes to think about the value)

Protected Variable:

protected int value;

public SubClassImpl() {
    value = 5;
}
  • Pros:

Can define a default value and sub-classes can just ignore it if they don't care.

  • Cons:

Authors of the sub-class aren't made aware of the existence of the variable, so they might be surprised by the default behaviour.

like image 547
DaveJohnston Avatar asked Feb 01 '11 14:02

DaveJohnston


1 Answers

Well, it depends...

  • Does the value have to be able to change during the lifetime of the object? If not, you might want to make it a protected constructor parameter, and make it a final private variable in your base class.

  • Might subclasses have reason to compute the variable based on other mutable state? If so, an abstract getter would be appropriate.

  • Otherwise, I'd probably use a private variable and a protected setter. I'm generally not a fan of non-private variables. This could allow you to react to changes in the value in your base class, such as changing other computer fields. To avoid the presence of a default value you could combine this with a constructor parameter to force an initial value which the subclass could change later via the setter.

like image 93
Jon Skeet Avatar answered Sep 27 '22 20:09

Jon Skeet