views:

145

answers:

7

My question involves specifically Java, abstract classes, and the use of protected data. I am being told that all the data should be private, and protected getters/setters used only.

Now, I understand we want to shield data from direct manipulation by casual users of the class, and that public data members in general are a questionable practice. I have looked at "Java protected fields vs public getters" ( http://stackoverflow.com/questions/2279662/java-protected-fields-vs-public-getters ), but I still am dubious that:

protected int i;  

is worse in an abstract class than:

private int i;  
protected int geti();  
protected void seti(int j); 

I am just not seeing the down side when the abstract class is there precisely to provide parent/common facility to the children classes, and the protected scope is meant to provide access to children, while protecting the data from casual users. I note in the question referenced above, that most of the answers seem to address the issue of why data in general should be private rather than public. I am trying to focus my question specifically on data existing in an abstract parent intended for use by the children. The sole reasonable comment I have heard to date is that using the parents protected data (e.g., int i above) leaves you with code in the child class that references a variable not declared in the child class. Less compelling is the argument (see http://stackoverflow.com/questions/3018739/common-protected-data-member-in-base-class ) that you may want to change the access some day, and now you have to honor your interface. This is an abstract class, and is intended to be extended 100% of the time.

Thanks! Specific Title/page# references to books are far more helpful that references to "..any basic Java programming text..."

========================================== 10-13-2010
This was as much a question about abstract classes as it is about protected data. I find it disappointing that the focus seems to have shifted in the responses to whether data hiding is a good thing in OOP (answer: yes). There's a lot of depth here involving the nature of the abstract class, and how it differs from a regular non-final class, and what possible advantages there might be for fixing the names and types of data-items in the abstract parent for use by the child classes. I think there is the possibility here for innovation and greater control being extended down from the abstract parent to the implementing child classes. I am concerned that general principles, such as the advantages of data-hiding, can become dogma, and inhibit innovation and the development of new patterns and ideas.

Thanks to all who contributed.

+7  A: 

If the field is private and access is through getters and setters, you will be able to reimplement getters and setters (for instance, dropping the field and updating/reading the value from an external source), and thus change how the "field" works without touching any child classes.

Whether this is worth it, that's up to you.

alex
This is argument #2, the "less compelling" stated in the question
cvsdave
Well, besides some minor package visibility details mentioned in other answers, I believe it's the only argument for making a field private with protected getters and setters.Personally, I don't think it's very compelling either... Getters and setters in Java are annoying.
alex
+3  A: 

Think of protected methods as an interface for subclasses, in the same way that public methods are an interface for everyone else.

Providing accessors enables the base class to maintain its state: there's no way a subclass would corrupt it without an intentional trick.

Samuel_xL
The base class, being abstract, can have no state, as it can not be implemented. I guess this is part of my reasoning; the sdame ruloes do not necessarily apply to an abstract parent as to a concrete parent. In this context, I think introducing the idea of interface perhaps distracts from the question, although it is an interesting thought. Thanks for your comment.
cvsdave
@cvsdave: The base class obviously *can* have state, or there'd be no reason to ask the question about whether and why (or why not) to expose it. What's more, the base class presumably has methods that rely on that field, and thereby on its validity. (If it doesn't, then the field doesn't belong in the base class at all, and only the getter and setter should be declared -- abstract, of course.)
cHao
+1  A: 

If you don't need your child to directly access it, why would you let them ?

It isn't a down side to use protected. But if it isn't necessary, maybe it's better to avoid it and control access on your fields.

Colin Hebert
A: 

If someone subclasses your class, and puts the subclass in the same package as your current class, they may want to override your getters and setters. For example, they wantto make sure that i may only be set to a value greater than 1.

Other than that, it's really up to you. The convention is that there are getters and setters for everything though.

Serplat
This is argument #2, the "less compelling" stated in the question.
cvsdave
Hmmm, I don't see how I missed that it was in there. Was that edited in afterwards?
Serplat
+1  A: 

In Java protected members are accessible to all members in the same package in addition to any extending classes. Making the field private will prevent classes in the same package from directly accessing it.

As well there is the point that alex raised earlier.

Rontologist
A: 

Information hiding is valuable, even among classes related by inheritance.

In addition to allowing re-implementation, as noted by alex above:

  • You can set breakpoints in methods.
  • You can add constraints in one place.
Andy Thomas-Cramer
A: 

Having less access isn't a drawback, it's a benefit. Classes should always limit access to as much of their internal state as possible. Don't think of why internals should be hidden, instead think of why they should be exposed. In this case as in every case, unless there is a really good reason to expose the variable then don't expose it.

Skip Head
How does this apply to the specific issue regarding abstract classes and protected? "...why they should be exposed..." this is exactly why the setter/getter is written in the alternative case. If access wasn't needed, the question would not apply!
cvsdave
Don't expose the field as protected. Make it private and use a getter and/or setter if necessary. This limits access as much as possible, which is always good.
Skip Head