Is It Good Practice to Make Member Variables Protected

Is it good practice to make member variables protected?

Encapsulation is one of the main features of OO. Encapsulating your data in classes means that users of the class can not break the class' data's invariants, because the class' state can only be manipulated through its member functions.

If you allow derived classes access to their base class' data, then derived classes need to take care to not to invalidate the base class' data's invariants. That throws encapsulation out of the window and is just wrong. (So do getters and setters, BTW.)

I find myself using protected less and less over the years, even for member functions. If a class fully implements a simple concept, then all of its state should be manipulatable through its public interface. If derived classes need "back doors" to sneak in, then I usually question my design. (Which isn't to say I never use protected. I just find I need it less and less.)

Should you ever use protected member variables?

Should you ever use protected member variables?

Depends on how picky you are about hiding state.

  • If you don't want any leaking of internal state, then declaring all your member variables private is the way to go.
  • If you don't really care that subclasses can access internal state, then protected is good enough.

If a developer comes along and subclasses your class they may mess it up because they don't understand it fully. With private members, other than the public interface, they can't see the implementation specific details of how things are being done which gives you the flexibility of changing it later.

What is the difference between private and protected members of C++ classes?

Private members are only accessible within the class defining them.

Protected members are accessible in the class that defines them and in classes that inherit from that class.

Edit: Both are also accessible by friends of their class, and in the case of protected members, by friends of their derived classes.

Edit 2: Use whatever makes sense in the context of your problem. You should try to make members private whenever you can to reduce coupling and protect the implementation of the base class, but if that's not possible then use protected members. Check C++ FAQ for a better understanding of the issue. This question about protected variables might also help.

Private vs Protected - Visibility Good-Practice Concern

No, you're not on the right track. A good rule of thumb is: make everything as private as possible. This makes your class more encapsulated, and allows for changing the internals of the class without affecting the code using your class.

If you design your class to be inheritable, then carefully choose what may be overridden and accessible from subclasses, and make that protected (and final, talking of Java, if you want to make it accessible but not overridable). But be aware that, as soon as you accept to have subclasses of your class, and there is a protected field or method, this field or method is part of the public API of the class, and may not be changed later without breaking subclasses.

A class that is not intended to be inherited should be made final (in Java). You might relax some access rules (private to protected, final to non-final) for the sake of unit-testing, but then document it, and make it clear that although the method is protected, it's not supposed to be overridden.

For polymorphic classes, is it OK to use protected instance variables?

is it considered acceptable to make them protected?

Yes. I don't think it will break the law of encapsulation when you use protected modifier. Allow only the subclass to access the instance, we still control what should be accessed by others and who can access the instance.

I could use getter methods in the subclasses to get the instance
variables, but that seems bizarre in this case

In some cases, you want to do some preprocessing before others can access the instance and you can put the preprocessing in the Getter.

private or protected variables?

In this case, the location of that image used to be a private, implementation-specific feature of the base class. Your new requirements meant that it needed to be able to vary from one derived class to another.

You should keep the member field private, but define a protected virtual property to expose it to derived classes:

private const string _defaultImagePath = @"C:\whatever.bmp";

protected virtual string ImagePath {
get {return _defaultImagePath;}
}

In the derived class that wants to change it:

private const string _myImagePath = @"C:\other.bmp";
protected override string ImagePath {
get {return _myImagePath;}
}

You will also want to change the base class so that it uses the property when it needs the image path, instead of using the field. This is the "Encapsulate Field" refactoring.

Confusion on when to use private vs protected fields

You nailed it yourself: a good practice is to make everything 'private' by default. Then, your specific design may require for example to be able to use some attributes or (preferably) some methods inside a subclass. In that situation, you'll need to move them toward 'protected' - but only in that situation.

Remember that using the accessors (getters & setters) is perfectly ok, and can be done without breaking encapsulation.



Related Topics



Leave a reply



Submit