Categories

Posts in this category

Thu, 09 Sep 2010

Protected Attributes Make No Sense


Permanent link

In C++, you can declare an attribute or a method as "protected". Which means that it is private, but subclasses can still access them.

This makes just as much sense as saying you only get access to these attributes if you wear a funny yellow hat.

I'll try to explain why.

Encapsulation has the advantage that you can change the implementation of a class without changing the API. If you write a library, that means you don't break your user's code if you change some internals.

However your users can not only instantiate your classes, but they can also inherit from them. Which means they can put a funny yellow hat on. There is no restriction as to who can inherit from your classes. Which makes protected attributes part of the public interface.

So, if you want to change the implementation of a class, you can't change how a protected attribute or method works, and what data it stores. If you do, you break all subclasses. Which not only exist in your own source tree, but in your user's source tree too. If you think that changing the implementation will also change protected attributes or methods, make them private.

So if protected methods are essentially part of the public API anyway, why not declare them as public? Why require your user to wear a funny yellow hat (aka declare an inheritance relation) while using your class? There is no good reason.

When seasoned C++ programmers hear that, they often respond with "but if I declare my private data as private a subclass doesn't have access to it! How can it work properly?". The answer is simple: You must provide a sufficiently powerful public API. Your users will be grateful.

One more thing: people often come up with an analogy to the real world, and claim that your kids also have access to your house or flat. This analogy is broken, because in the real world the parents have to take actions to get children (or give somebody the same status as your children). In the programming world, every outsider can write a child class of your classes.

(The reason I posted this in the Perl 6 section of this blog is that Perl 6 has no protected attributes. Which has spawned many interesting discussions, which were the precursor to this blog post.)

[/perl-6] Permanent link

Comments / Trackbacks:

Trackback URL: /blog-en/perl-6/protected-attributes-make-no-sense.trackback

Rachel Blum wrote


Actually, they sometimes do make sense. Especially as so-called 'customization points'.

This allows you to override certain internal functionality of your class that is only called by the class and its descendants.

Simple example: You have a FetchData class that gets data from a remote resource. One of the customization points is OnConnectionEstablished - different subclasses can take different actions whenever a connection is established. (Because they might need to send certain handshake/config info, whatever)

It makes no sense to call that outside of the class, but derived classes need access to override - hence, protected. (The main issue here is that C++ conflates inheritance and access protections)

Now, I'd make the point that protected and private members in C++ are a disaster for introspective testing (since you can't actually introspect...), but that's a different kettle of fish

Claudio wrote

protected in Java
One of the better Java books out there (Core Java, vol I) has this to say on the matter:
"Dont use protected fields" (8th ed., p 238). The first reason is subclassing, as you explained, and the second is rather Java specific (all classes in package have access).

On the other hand, protected fields (or methods) are useful for the same reason Rachel points out: a kind of marker to indicate something that is not ready for general use and *should* be redifined (read overridden) in a subclass.

Bas Mommenhof wrote

Software dev with one eye on architecture
I tend to disagree with your point. I am writing code using C# and I like to use protected methods for extension.

I use then when I create a class that is intended to be overriden (subclassed) and the protected method is used as an extension point.
Often this method does not contain any code itself but a subclass can add implementation to do some special processing before or after a certain method is executed.
The method can be even defined as "abstract" which means that the no implementation exists in the base class and MUST be overriden.
The fact that a method is protected (to me) indicates that this method has carefully been designed to be overridden.

Through experience I have learned that public methods should never be overridable, because this takes away the garuanteed order in which your code is executed. If you want more information on that let me know and I will take the time to explain. Suffice to say that I have regreted almost every public overridable method I ever made (and converted them to protected).

Also, when you define the class or method as internal (friendly) it means it can only be called or overriden from the same module as the original class is defined.
You can use this to create helper methods that allow your object to get some things done really fast or in a generic way, and not worry about this methods being abused by some external (and thus evil) code written by somebody that not fully understands every minute detail about your class and the way you intended it to be used.
Because face it, these are the truths about programming:
Nobody likes to write documentation, so it's always too little.
Nobody likes to read documentation, so it's always too much.
Even after reading the documentation, the only real way to understand what that documentation meant is create some code and fiddle with it.
The first attempt always fails the first time, so you repeat previous step.

My point is that because something is protected, it does not automatically mean it is public by 'indirection'.
So, protected methods have several usefull functions, mostly to do with the patterns you wish implement within your class.

Greetings.
(ps, if C# and C++ differ greatly on the workings of protected, then this al may make no sense at all, but I believe they arre fairly similar)

Bas Mommenhof wrote


(darn, they beat me to the punch)

rhebus wrote


I agree in principle.

Some methods are open for overriding, but not for calling. Unfortunately, protected isn't quite the right tool for the job. One wants a method that really *can't* be called, but *can* be overridden. But in most languages, protected is the closest you can get. Is there anything in perl 6 which is private-but-overridable?

There's also the case of the protected nonvirtual destructor, useful in C++: http://www.gotw.ca/publications/mill18.htm -- this use case generally doesn't appear in any language with a GC.

George wrote


I'm not going to pontificate on the theoretical benefits and drawbacks of protected members. What I will say, though, is that a massive number of the bugs I've fixed over the years were caused by the use of protected members

Aivar wrote


I would say that protected members are public members with the twist that you can't call them from outside current class.

Tom Dyess wrote

Protected
I use protected member variables when I'm subclassing and I want access to variables I don't want users of the object to have access to.

I'm using the assumption that if you are just instantiating an object, it should encapsulate data as usual, but if you are inheriting that object, you should have full access to anything that object does, and that you know what you are doing. I hate classes that protect me from myself by limiting my use of that class as a parent class.

Dave wrote

I agree, protected attributes make no sense
But you didn't argue that. You argued that protected methods also make no sense. That is just plain wrong. Protected methods are very useful for defining where the original class writer expected their class to be extended. Yes, maybe you want to use their class in a way the author didn't intend for it to be used, but making everything public isn't going to help. It's going to hurt, a lot. And if you REALLY want to do that, just #define protected as public. Just don't expect anyone to handle your bug report.

Inepologlou Lazarus wrote

Software Architect
Public and protected are two different interfaces of the same class that are targeted to different people. The fact that most people will make use of the public interface does not mean that the protected interface is useless: in fact it is very useful for those who work on framework development.

On the other hand, you don't have to invent new uses of the protected interface ("funny yellow hats") if your requirements are nicely covered by the public one!

Markus Mayr wrote


While I agree that protected attributes make no sense, or would only make sense whenever a public attribute would do as well (and these cases are rare). This breaks with the aim to encapsulate a certain part of the program logic into the class most of the time.

However, protected methods are very useful for the above mentioned reasons, i.e. overriding. I consider them as part of the public API. But I think, it can be helpful for the user if he is told "You won't need these methods, unless you want to customize behaviour of this class. What? You really want to? Then please take a yellow hat, read the rules and go on."

This also helps the user to structure his code, as he does not need to encode the desired behaviour into weird and maybe incredible long parameter lists, but he can encapsulate it himself in a (sub) class. You as a developer can use this as well.

In all my code, I could simply replace the protected: line with a public: line and everything would still work and I would still be able to change the internal workings of my classes. It's merely a help for the user of this class in almost all cases.

Therefore, I agree that protected is not essential, but it is definitly nice to have.

Peter Gerdes wrote

Multiple APIs
Basically this comes down to the fact that it can be useful to provide different APIs to different consumers.

To give a simple example imagine I have some kind of data structure that allows search, insertion and delete. For instance perhaps it's a B-tree used to organize filesystem data on disk. Now as a client of this data the only API I should have access to is a generic insert, delete, search API so my code is agnostic as to whether a B-tree or even a linked list is used to store the data. On the other hand if I'm writing filesystem code that tries to efficently and atomicly update this data on disk I may need much deeper access.

Ideally a programming language would support multiple different interfaces to the same object to enable fine grained separation of concerns. Protected attributes are really just a simply way to present two different interfaces, one to extenders who need greater access and another to consumers.

---

Well also protected attributes are useful because C++ doesn't let you intercept setting and getting an attribute so making an attribute protected allows you to keep all accesses of that attribute in a localized part of your code so you don't have to change your whole codebase if you realize that every time obj.x is set to 0 you should really increment obj.count.

Write a comment

The comments on this blog post have been disabled; the comment form below will not work.

 
Name:
URL: [http://www.example.com/] (optional)
Title: (optional)
Comments:
Save my Name and URL/Email for next time