Previous Section  < Free Open Study >  Next Section

5.5 Private, Protected, and Public Inheritance à la C+ +

If you are, or will be, a C++ programmer, there is a note of caution pertaining to inheritance relationships. The C++ language has implemented relationships called private inheritance, protected inheritance, and public inheritance. The public inheritance relationship is synonymous with the definition of inheritance in the object-oriented paradigm. The private and protected inheritance relationships are used to capture the notion of "inheritance for implementation." The semantics of these relationships are such that the derived class gets a copy of the base class data (with the same access rules of public inheritance); the implementors of the derived class get access to the public section of the base class; but the users of the derived class do not get access to the public section of the base class. In short, private and protected inheritance are the containment relationship. They do not capture the notion of either specialization or categorization. The difference between private and protected inheritance is that protected inheritance allows implementors of grandchildren (derived classes of the derived class) to use the public section of the base class; private inheritance does not.

Since classes can be inherited only once in C++, these relationships are actually a warped form of containment in that the containing class can contain only one object of the specified type. A good heuristic for C++ is to avoid the use of private and protected inheritance, using containment via data members instead. While I can find many C++ programmers who will argue that they know what they are doing and want to use C++'s inheritance relationship to implement containment, they are doing a great disservice to their maintenance people (which is probably them three months later when they cannot remember what they implemented). A serious pitfall in the object-oriented paradigm is confusing the use of containment and inheritance relationships. Using an inheritance syntax to implement containment muddies the waters all the more. In the name of readability, only public inheritance should be used in the C++ language.

The following facts are true, independent of the form of inheritance used (i.e., private, protected, or public inheritance) in the example in Figure 5.8).

Figure 5.8. The differences between public, protected, and private inheritance.

graphics/05fig08.gif

  1. Anything in the private section of a class can be accessed only by implementors of that class, that is, only the implementors of Fruit can access weight and color in the private section of Fruit; only the implementors of Apple can access taste and seednum in the private section of Apple; and only the implementors of MacintoshApple can access the OrchardLocation in the private section of MacintoshApple.

  2. Anything in the protected section of a class can only be accessed by implementors of that class or a derived class, that is, the get_weight method of Fruit can be accessed by implementors of Fruit, Apple, or MacintoshApple; the get_seednum method of Apple can be accessed by implementors of Apple or MacintoshApple.

  3. Anything in the public section of a class can be accessed by implementors of that class or direct users of that class, that is, the print, cost, and eat methods of Fruit are visible to implementors and users of Fruit; the core and bake methods of Apple are visible to implementors and users of Apple; and the pick_your_own method of the MacintoshApple is visible to implementors and users of MacintoshApple.

  4. Anything in the public interface of a class can be accessed by implementors of its immediate derived class, that is, the print, cost, and eat methods of Fruit are visible to implementors of Apple; the bake and core methods of Apple are visible to implementors of MacintoshApple.

The only remaining questions are the following:

Can users of Apple access the public interface of Fruit?

Can users of MacintoshApple access the public interface of Apple?

Can implementors of MacintoshApple access the public interface of Fruit?

If we use public inheritance, whose semantics state that the public interface of the base class appears to be copied into the public interface of the derived class, then the answer to all three questions is yes. If we use protected inheritance, whose semantics state that the public interface of the base class appears to be copied into the protected section of the derived class, then the users of Apple and MacintoshApple cannot access the eat, cost, and print operations since users of a class cannot access the contents of the protected section of a class. However, implementors of MacintoshApple can access the protected section of Apple so they can use the public methods of Fruit. Therefore, the answers to the three key questions are no, no, and yes. Lastly, if we use private inheritance, whose semantics state that the public interface of the base class appears to be copied into the private section of the derived class, then the answer would be no to all three questions since only the implementors of a class can see the private members of a class.

If all of this appears confusing, you are in good company. Private and protected inheritance are simply warped forms of containment and should be avoided. The fact that C++ has implemented these concepts warrants their treatment in this text. All future references to inheritance in this text are synonymous with public inheritance in C++. The reason I balk at creating heuristics telling designers to avoid using private and protected inheritance is that I want the heuristics to be language-independent. Also, both of these constructs have a well-founded theoretic backing (inheritance for implementation). The real problem with their use is understandability on the part of a system architect who is looking at code which uses these constructs. He or she is likely to think about the semantics of specialization when seeing the syntax of private inheritance, when in fact he or she is examining containment.

    Previous Section  < Free Open Study >  Next Section