2

I was recently given advice to change all my protected member variables in the base class to private access.

But the only advantage that comes to mind in terms of real usage is to just be able to give separate Read, Write and Read/Write access to them to protect against misuse. The following Java code details this use.

public class BaseClass {
    protected Object protectedMember;

    private Object privateMemberR;
    private Object privateMemberW;
    private Object privateMemberRW;

    public BaseClass() {

    } 

    protected final Object getPrivateMemberR(Object obj){
        return privateMemberR;
    }

    protected final void setPrivateMemberW(Object obj){
        privateMemberW = obj;
    }

    protected final Object getPrivateMemberRW(Object obj){
        return privateMemberRW;
    }

    protected final void setPrivateMemberRW(Object obj){
         privateMemberRW = obj;
    }
}

Maybe declaring them final is not always needed, only to be sure that they are not overwritten and misused.

I read similar arguments like this Clean code questions, but if I could have gotten away with private member variables, I would have made them private in the first place.

Furthermore, since at least in Java you can only have the access modifier for an overwritten method to allow more, but not less, access than the superclass method, you are still gonna drag either protected member variables or protected getters and setters all the way up in your subclasses.

I have not considered multiple inheritance since Java does not allow it, but still I do not see how using standard notation for getters and setters you could avoid running into problems.

Is there any other actual benefit in terms of real usage (other than it looks more pretty and easier to read, magically hope you protec against improper use by replacing direct reference with getters and setters)

Community
  • 1
  • 1
Radu Ionescu
  • 3,462
  • 5
  • 24
  • 43

2 Answers2

1

It actually really depends on the context. It's more of a preference question depending on your design.

For instance, you know that the only difference between private and protected are the subclass and package access.

            | Class | Package | Subclass | World
————————————+———————+—————————+——————————+———————
protected   |  y    |    y    |    y     |   n
————————————+———————+—————————+——————————+———————
private     |  y    |    n    |    n     |   n

It also seem "easier to code" because a subclass can access a protected field directly, rather than using a method to access a private field in the superclass, but that might be defeating the purpose...

You have to check your inheritance and make sure you don't let any holes while using protected. Direct access to your subclass for instance?

private : someone might not be able to do what they want with your implementation.

others : someone may be able to do something you really don't want them to do with your implementation.

Reasons to use private instead of protected for fields and methods

In my opinion, there needs to be a special reason why you would make something any more accessible than private...

Community
  • 1
  • 1
fneron
  • 1,057
  • 3
  • 15
  • 39
1

It depends really. Without knowing what concrete reasons exist for a subclass to be able to access a field, its hard to argue what protection level is appropiate.

A big factor in the decision is if the class is intended for subclassing; if it isn't explicitly designed to be extensible then keeping its inner workings private is a reasonable default choice.

It gets hairy when the class is intended to be subclassed and the subclass needs to have some control over the base class.

If the subclass clearly needs to both read and write a field, then all that protected getters/setters for a private field can buy you, is:

a.) The possibility to validate and respond to improper use (e.g. by throwing) at the point where it occurs, not later. This can save a lot of time by avoiding scenarios where at one point a field is altered improperly, resulting in a problem much later in an unrelated place.

b.) The flexibiliy to alter the field representation without needing to change existing subclasses. I think thats a pretty rare case; if the field type can change and subclasses are tied closely to the base class, its unlikely you get away with just converting the representation in a getter/setter.

c.) If the subclass just needs to read a field, then its obvious that just providing a getter defends against the subclass altering that field. No available setter clearly communicates that this member is not intended to be altered. If possible, making the field final can be an alternative to providing a protected getter.

There may be an alternative: package private access

Thats an option that is often overlooked. In many cases you want a base class providing the most generic implementation and then two or more variants that a user can extend from. The variations need to access the base class member, but the user derived subclasses shouldn't. Then package private is just the tool for the job.

Durandal
  • 19,919
  • 4
  • 36
  • 70