0

This question already has an answer here:

There is an abstract BaseGame class that will be inherited by specific game classes.

This class has an attribute requestHandler that will be used in all subclasses and should be initialized in the constructor, so I put this constructor in superclass.

Is it better (make more sense) to keep requestHandler private (case 1) and access it in subclasses via accessors or make it protected (case 2) and access it directly? Are there any implications in the use of case 1 or case 2, or it just does not matter?

case1:

public abstract class BaseGame {

    private RequestHandler requestHandler;

    protected BaseGame(RequestHandler requestHand) {
        this.requestHandler = requestHand;
    }

    protected RequestHandler getRequestHandler() {
        return requestHandler;
    }
}

public class SoccerGame extends BaseGame {

    public SoccerGame(RequestHandler requestHand) {
        super(requestHand);
    }    

    public void doSoccerGame() {
        getRequestHandler().submitScore(10);
    }

}

case 2:

public abstract class BaseGame {

    protected RequestHandler requestHandler;

    protected BaseGame(RequestHandler requestHand) {
        this.requestHandler = requestHand;
    }
}

public class SoccerGame extends BaseGame {

    public SoccerGame(RequestHandler requestHand) {
        super(requestHand);
    }    

    public void doSoccerGame() {
        requestHandler.submitScore(10);
    }
}

marked as duplicate by gnat, user22815, Ixrec, Kilian Foth, Ampt Apr 24 '15 at 17:36

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 3
    The relationship between a class with protected fields and its subclasses is exactly the same as a class with public fields and unrelated classes. In both cases you've created a dependency on the fields of the class and won't be able to change those fields freely in the future. This may not be a problem, depending on whether you control all the code that would need to be fixed in the event that you do need to change the fields for whatever reason. – Doval Apr 21 '15 at 19:12
3

Contrary to popular belief, accessor methods do not provide any great advantage over direct field accesses, while in java they do tend to clutter the code with lots of gets and ()s. (Compare with C#, which has an awesome feature called properties, which look like fields but behave like accessors, saving you from all the mindless getSuchAndSuch()s and setSuchAndSuch()s.)

However, "no great advantage" does not mean no advantage at all. The advantages of using accessor methods instead of direct field access are as follows:

  1. If you need to maintain binary compatibility, then you must use accessor methods, so that the class containing the fields can be modified without breaking code that has already been written to use the class. (Binary compatibility means compatibility without the necessity to modify and recompile one of the two parties. Since you are writing both the base class and its descendants, this does not apply to you.)

  2. Accessor methods are often inevitable, while direct field access is never inevitable, so going with the "always use accessors" doctrine simplifies things and introduces homogeneity over the entire code base.

  3. As you refactor the code trying various what-if scenarios, sometimes you discover that you have a field which needs to be replaced by a computation, which in turn means that it has to be encapsulated by an accessor method, and sometimes you discover that you have a field which stores the result of a computation and therefore does not have to be hidden behind an accessor method, so the accessor can go and the field can be made protected or public. If you keep doing this kind of refactoring a lot, then you might get to a point where you might say "aw, forget it!" and hide all fields behind accessor methods so that you don't have to keep refactoring more classes than the one you are working on.

  4. When writing code in java and using a decent IDE, when you have an object and you want to get something from it, you tend to type myObject.get and then the IDE shows you a list of auto-completion options, so you have everything that you can "get" from the object right in front of you. If you use fields, then you have to stop at myObject. and browse through a list which contains everything, not only just things that can be gotten from the object. The same applies with myObject.set when you want to set something.

In either case, I would never make a non-final field anything but private. Luckily, in your case, your requestHandler seems to be a prime candidate for being final, (it probably only gets set in the constructor and never again,) so it is quite legitimate to make it final and protected.

  • You are right, I'll make requestHandler final. Besides advantages you mention, since the class is abstract and requestHandler is intented to be used by subclasses (there is not intention to use it in BaseGame), conceptually doesn't make more sense to use it without accessors? I mean... Since it's a attribute that belong to all subclasses, it's like it were directly on SoccerGame as a private instance, for example. If so, I would not give accessors to it and use it like case 2. Is't it? – alexpfx Apr 22 '15 at 15:27
  • Yes, I usually go with direct field access. I might give it 2 seconds of thought if the field is to be public, but I will not think about it for longer than a second if the field is protected. – Mike Nakis Apr 22 '15 at 15:59

Not the answer you're looking for? Browse other questions tagged or ask your own question.