I found those two terms in the book of Meyers, but what is the difference?
Interface inheritance is public inheritance, while implementation inheritance is private inheritance.
If class B publicly inherits from A, B is an A: it inherits the whole interface of A, and a (reference/pointer to) a B object can be automatically be upcasted to A, and used wherever an object of A is expected. However, if B privately inherits from A, B is-implemented-in-terms-of A: only the implementation of A is inherited, not its interface. Thus (references/pointers to) B objects can not be used in places where A objects are expected.
Update
To reflect on #Michal's comment, here are some links (based largely on googling "c++ implementation inheritance") to demonstrate the common usage of these terms in the context of C++:
C++ Design/Coding tips - Part 7
Interfaces
Uses and Abuses of Inheritance, Part 1
Implementation (or class) inheritance is when you separate a common part of implementation in the base class.
Interface inheritance is when you use virtual methods. It is intended to separate interface from implementation and minimize dependencies between program elements.
The major difference is interface is public inheritance and implementation is private inheritance.
The data members and method of the public and protected section will be inherited from base class to derived class in their respective access specifier in public inheritance.At the same time the object of derived class can access the data members of base class as the normal method.
The data members and methods of public and protected section will be inherited from base class to derived class in private access specifier
Here's the difference between the two types of inheritance according to "Taligent's Guide to Designing Programs".
Inheritance
There are two forms of inheritance in C++: type inheritance and implementation inheritance. In both forms of inheritance, a derived class can share or override behavior inherited from a base class. However, use type inheritance only when it is necessary for a derived class to inherit type information as well. The primary reason to inherit type information is to allow for polymorphism.
Express type inheritance by deriving a class from a public base class; express implementation inheritance by deriving a class from a private or protected base class.
More at:
https://root.cern/TaligentDocs/TaligentOnline/DocumentRoot/1.0/Docs/books/WM/WM_23.html
Related
In C++, one can create a sub-class via public, protected, or private inheritance. What's the notation to indicate that in a UML class diagram? I'm thinking about putting a label on the arrow but not sure if that's common practice.
What is private inheritance in C++?
Private inheritance in C++, such as:
class B1 {
public:
void test();
...
};
class D1 : private B1 {
public:
void demo() { test(); }
...
};
means that every instance of D1 is an instance of B1, but that is hidden for the outside world. This strange construct aims at implementing the derived class by reusing the code of the base class, but as if there would be no inheritance.
In consequence, unlike public inheritance, a D1 object could not be used where a B1 object is expected:
B1 *p = new D1; //ouch -> error: ‘B1’ is an inaccessible base of ‘D1’
Is this UML inheritance?
In UML, when a derived class specializes a more general base classe, it means the following:
Type conformance means that if one Type conforms to another, then any instance of the first Type may be used as the value of a TypedElement whose type is declared to be the second Type. A Classifier is a Type, and conforms to itself and to all of its generalizations.
So in UML, if D1 specialises (i.e. inherits from) B1, a D1 instance could always be be used in place of a B1 object. This does not match the C++ private inheritance.
Moreover, there is not either a realization relationship between an interface and its implementations either, since D1 does not conform to the interface defined by B1:
An InterfaceRealization relationship between a BehavioredClassifier and an Interface implies that the BehavioredClassifier conforms to the contract specified by the Interface by supporting the set of Features owned by the Interface, and any of its parent Interfaces.
How to represent it in standard UML?
Obviously, there is a dependency: D1 depends on B1. So you could simply show a dependency. But this does not really help to grasp the kind of relationship and is not very useful. (unless you add a comment to explain)
A better approach would therefore be to map UML to match the C++ semantics. In this regard, you could envisage to model the private inheritance as a composition relation:
Why? Because the situation is very similar (although not completely) to the following composition alternative:
class B2 {
public:
void test();
...
};
class D2 {
private:
B2 base; // instead of private inheritance
public:
void demo() { base.test(); } // base members accessed via base
...
};
So all we do in the UML model here, is to make explicit that in any D1 instance, there is a B1 sub-object not accessible directly from the outside world.
Edit: Other alternatives?
In the former and now obsolete UML 1.4, a generalization relationship could have a stereotype «Implementation» that would have fulfilled your need, but is no longer supported since 2005, and might mislead some readers who associate "implementation" with interface:
Specifies that the child inherits the implementation of the parent (its attributes, operations and methods) but does not make public the supplier's interface, nor guarantee to suport them, thereby violating substituability. This is private inheritance and is usually used only for programming implementation puproposes.
Digging a little bit in the UML metamodel, it appears that generalization has a isSubstitutable property which is true by default. So you could think of using your own language-specific profile, and define therein a stereotypes «Private inheritance» and «Protected inheritance» for a specialization of the Generalization metamodel element, both with isSubstituable=false. This would allow:
This could be a very pragmatic and readable way to convey your language-specific design intent, including that a D1 object is not substituable for B1. But be aware that this is not without risks: isSubsituable is only about run time promises, and has in reality no impact regarding inheritance rules of public features in UML. Automated tools might therefore come to a different conclusion than your readers (this is why I proposed another approach above).
I would say with UML it's usually the type of relationship it has for example one to one or one to many. If you are deriving from an abstract class, interface or just another base class. Usually during inheritance you would use the protected keyword so that everything is private to any class outside of inheritance.
After inheriting from a base class you can also override methods from the base class as well as run the base method from inside the overridden method.
I believe what you are looking for here is the protected keyword which basically is private inheritance. Only related classes have the ability to access such members. For example, you create a base class with protected members and then use these members in inherited classes or classes that derive from the base.
Here is more info
https://www.tutorialspoint.com/cplusplus/cpp_inheritance.htm
I have a function public void myFunction(foo); and public void myFunction(foo, bar); in my parent class. I want these functions included in my derived class, but privately. You can declare it in the derived class' private section by using BaseClass::myFunction(). Note that it doesnt take any parameters in the function. But if there are two implementations of myFunction like I have in my case, it won't work since it can't distinguish between the two functions. How do I implement both functions privately?
Based on what you've said in your comment about your professor's instruction to use inheritance, more than whether it's a good design choice, I think you are expected to use private inheritance.
Private inheritance is a valid feature of C++, but its often not a good design choice. I wont go into that, I'm not recommending it in general, I'll leave you to look it up elsewhere on SO, but also recommend Scott Meyer's books effective C++ & more effective C++ which covers this.
(protected inheritance on the other hand is very unusual)
In your question you seem to be starting from public inheritance and trying to make some inherited functionality private via using. This is a bad design choice as mentioned in comments. It violates the Liskov substitution principle. Since PUBLIC inheritance implies is-a, we can imagine the code that creates a base class reference to an object of the derived type, what then is supposed to happen when we try to call the hidden functionality with that base class reference?
Derived d;
Base& b = d;
b.HiddenFunction(); // calling the function on d even though you thought you hid it
If instead you use private inheritance you can then use using to publicise those privately inherited functions which are safe to expose on the derived class.
class OrderedLinkedList : private LinkedList
{
public:
using LinkedList::ItemCount; // expose some specific base functionality
};
If using doesn't do the job due to overloaded functions, then you can add just those overloads that you want to provide and implement them just by calling the base function. In such cases, if you need to clarify whether to call the base or derived version you can prefix the function name with the class name e.g.
void SomeFunction()
{
// call base version, not this derived version recursively
NameOfBaseClass::SomeFunction();
}
Within the derived class implementation, the public and protected members of the (privately) inherited base class are accessible without the need to do anything like add a using.
Private inheritance is not an is-a relationship like public inheritance since we cannot refer to the derived objects as references/pointers to the base. Private inheritance is "implemented-in-terms-of".
Since private inheritance is not an is-a, one cannot substitute such derived objects for the base and as such the liskov substitution principle just doesn't apply.
With regards to a class, what does an interface mean? I think it refers to all the public functions of the class. Am I correct or does it mean something else?
I keep hearing it a lot but never quite noticed the explicit definition.
This one's the real question. What does it mean for a derived class to retain the interface of the base class it's derived from? I think it means that the public functions in the base class must be public in the derived class as well (which will be the case in public and protected inheritance). Am I mistaken?
Yes, the interface of a class is the collection of its visible member functions to the outside world, i.e. its public member functions. Some also include member variables in the interface, but it is not usually common to have public member variables (unless declared static). Most often, interfaces are implemented via abstract base classes. This is in contrast to Java, which has a different keyword for specifying interfaces.
Retaining the interface means having the public member functions in the base class visible across the class hierarchy. Also, you can override virtual functions so you get polymorphic behaviour, keeping the common interface. Note that only public inheritance preserves the interface, protected and private do not. Another way of failing to retain an interface is via name hiding in C++. Example: re-declaring Base::f(int) as Derived::f(float,float). In this case, the Base::f(int) is not longer visible in Derived, unless via a using Base::f; statement.
In composition, one class explicitly contains the other. However in Inheritance, the base class is implicitly contained in the derived class. Correct or not? I ask this because after several days of studying inheritance, it's only today that I got to read somewhere that an object of a derived class always contains an object of it's base class.
I mean, I thought that there would be only one object and just the functionality would be inherited but I didn't know that it would also contain an object of the base class within.
In Composition, one object contained another object. While in inheritance, your object is acquire properties of base class.
I mean, I thought that there would be only one object and just the
functionality would be inherited but I didn't know that it would also
contain an object of the base class within.
Yes you are right, there will be only one object and functionality is getting inherited. Even if your base class have member variables, there size will getting added to your object size.
You can directly call public and protected methods of base class. While in cointainership you are only able to access public methods.
That's should be:
In composition, one class explicitly contains an object of the other class. However in Inheritance, the base class is implicitly contained in the derived class.
In short:
Composition is about the relationship of class and object.
Inheritance is about the relationship of class and class.
And please remember "Prefer composition over inheritance".
Prefer composition over inheritance?
In general derived class contains all data members and shares the properties/methods of base class, but there is a difference between composition and inheritance.
By "composition" you mean that one object "has" some other object. In example: human has a liver. In class design it can be presented like below:
class Liver {};
class Human
{
public:
Human() {}
private:
Liver mLiver;
}
When talking about an inheritance, there are 2 options: public inheritance roughly says that one object "is" a kind of other object. In example: Human is a kind of living creature. It does not sound naturally to say that human "has" a living creature inside. Public inheritance is a way to go in such case:
class LivingCreature {};
class Human : public LivingCreature
{
public:
Human() {}
}
Other option is protected/private inheritance, which should be used to implement some object "in terms of" other object. Generally it can also be treated as kind of composition, but first approach is usually better.
Summarizing:
If you can say that one object "is" a kind of other, more general object: public inheritance is the best way to go,
If you can say that one object "has" other object: use composition.
Consider the code:
class Engine
{
//Some Code
};
class Vehicle
{
//Some Code
};
class Car:Vehicle
{
Engine engine;
//Some Code
};
In this case class Car inherits the class Vehicle. An object of the class Car doesn't contain an object Vehicle, rather it is an object of the class Vehicle (Inheritance). On the other hand it does contain an object of the class Engine(Composition).
The fact that you can access a parent's function with this comes from the fact that the Car object is a Vehicle not because it contains an Vehicle object.
In composition, one class explicitly contains the other. However in Inheritance, the base class is implicitly contained in the derived class. Correct or not?
It's entirely a matter of knowledge/perspective: if you're aware that inheritance means a base class instance will be embedded in the derived class then saying class Dervived : Base can be seen as explicitly requesting that, while if you're aware that defining a variable inside class X means it's a member variable that will be contained in instances of X, then that can be seen as explicit too.
I ask this because after several days of studying inheritance, it's only today that I got to read somewhere that an object of a derived class always contains an object of it's [sic] base class.
The distinction between actually containing a base class object vs. through some more unspecified/mysterious means being substitutable for a base class instance on occasion, isn't necessarily the most important thing when starting to learn about inheritance, so it's easy to imagine it isn't emphasised in all learning material.
I mean, I thought that there would be only one object and just the functionality would be inherited but I didn't know that it would also contain an object of the base class within.
At an implementation level, it's important that it actually contains a base class instance, so code compiled to handle base class objects can work equally well on derived class instances. The C++ Standard could have deemed it merely an embedded copy of base class content with identical binary layout while not an actual base class object, but then a huge amount of text in the Standard would have to be added to mention that the derived objects could be used in scenarios where a base class instance was acceptable. In other words, the distinction is somewhat arbitrary, but it's easier for everyone if it's both intuitive and lends itself naturally to simpler, more concise Standard wording.
Inheritance vs Composition:: Is my understanding correct?
Conceptual differences:
Inheritance:
In case of inheritance, derived class is sub-type of base class.
Meaning if you derive Dog from Animal, then Dog is Animal and
all* operations that can be performed on Animal can be performed on Dog.
Using private, protected and public inheritance, however, you can control who knows that Dog is Animal and who knows inner workings of Animal. In case of protected or private inheritance only Dog will know that it is Animal, but it won't be obvious from the outside.
Composition:
In case of composition one class is included into another.
a Car is not a Wheel. But it contains Wheel. So operations that work on Wheel will not work on a Car.
By declaring member variable of type Wheel as public, private or protected you can control who can access Car's Wheels.
I believe that is clear enough?
Implementation details:
In case of C++, members of base class are included into derived class. Also methods that existed in base class will be accessible in derived class - somewhere. Access specifiers private, public and protected AND inheritance type determine which methods are visible and where.
I thought that there would be only one object
It is one object.
In microsoft compiler and g++ objects are "merged" together, meaning that in case of:
struct Base{
int a;
};
strict Derived: public Base{
int b;
};
Derived internally will probably (would need to check C++ standard to be sure) have this layout.
strict Derived{
int a;
int c;
};
or
struct Derived{
Base _;
int c;
};
In case of multiple inheritance and diamond inheritance things will get more complicated and base class can be included multiple times.
I've got some confusions on the access level in C++ inheritance and more generally how I should design a C++ class.
class Car
{
public:
private:
string brandName;
}
class Sedan: public Car
{
public:
// this function needs to know the Sedan's brandName
void someFun()
{
brandName = "sss"; // error!!!
}
private:
}
In the above example the Car as a base class has a private member "brandName", and the Sedan as a derived class from Car inherits that member "brandName". As explained in Effective C++, public inheritance makes an "is-a" relationship, which means Sedan is a Car, now can I say that Sedan has a "brandName"?. If the answer is yes, why couldn't Sedan access to its own attribute in someFun?
I know the solution is to change brandName's access level to protected, my confusion is that what features or conditions make a variable member to which access level, in other word how I decide which access level should a given member be attached to?
I'd also like it if you'd recommend any book or article elaborating on this topic.
now can I say that Sedan has a "brandName"?
No, neither has Car. The brandName is an implementatin detail, private, hidden from anyone else and does not contribute to the class' public interface, which is what makes the nature of a Car. So while technically there is a brandName somewhere in a Car and thus in a Sedan, from a pure OO view that does not matter. Similar to "Is-A"-relationships that are expressed only by public inheritance and not by private inheritance, "Has-A"-relationships in the OO point of view are only present if the composition or assoctiation is publicly accessible/visible (mostly via getters/setters).
juanchopanza's answer and the comments to it have lead me to sneak a little around the web, trying to find resources about Is-A and Has-An relationships. this transcription seems to indicate that the two terms did not originate from OO thoughts. In fact, OO literature seems to cite the Liskov Substitution Principle instead of using "Is-A" relationships. It lays stress on encapsulation and opaque objects, so it concerns mostly with public interfaces of classes and how their behavior affect associated objects. While a "Has-A" relationship can be association, it also can be aggregation. In this case, since the brandName is not an external, associated object (in C++ we would express that fact with a pointer or reference member), it is an aggregation-"Has-A", hidden in the opaque Car and therefore not of interest for OO (and the above answer is left semantically valid).
I know the solution is to change brandName's access level to protected
NO! brandName's access level has to remain private, so that Car has the complete control over what happens to it. If you want to access it in derived classes, provide protected getters and/or setters.
I'd also like it if you'd recommend any book or article elaborating on this topic.
Any book about object oriented design should do. If you read through two or more of them, you will get a good idea of what to do and what not to do.
can I say that Sedan has a "brandName"?.
Yes, it certainly has an object of type string called Car::brandName (whether this constitutes an OOP "has-a" relationship isn't entirely clear to me, but probably not: see comments)
If the answer is yes, why couldn't Sedan access to its own attribute in someFun?
Simple because brandName is private. Those are the rules of the language. If you want to give a derived class access to a non-public data member, you can make it protected.
I'd also like it if you'd recommend any book or article elaborating on this topic.
There is a list of books here. Perhaps "The C++ Programming Language" would be good for explaining this particular aspect.
you have hidder brandName from the outer world, by making it private. Make it protected so that children may inherit it. To understand inheritance rules regarding specifiers, go to HERE
Public members are free to all to use.
Private members are for the use of only this current class, and no one else. It is used mostly for inner members of the class to use and save for it's own purposes or to provide a method to access to them.
Protected members are accessible for inherited classes, just as your example shows - brandName is for the use of inherit classes, so it should be protected.
I've got some confusions on the access level in C++ inheritance and more generally how I should design a C++ class.
C++ has three access level specifiers that can be used when inheriting:
private, protected and public
class Derived : public Base
Is called public inheritance and represents IsA relationship. When inheriting publicly, public members of the base remain public in Derived, protected members remain protected in Derived and private members are private (and not accessible from Derived).
class Derived : protected Base
Is called protected inheritance. This kind of inheritance is rare, and would be used if you don't want to expose the public part of Base when accessed as derived (or through the interface of Derived). In this kind of inheritance the public members in base become protected in derived.
Also see the C++ FAQs
class Derived : private Base
Is called private inheritance. This kind of inheritance can be used to simulate containment (Herb Sutter - Uses and abuses of inheritance). Here public members in Base become private when accessed through the interface of derived.
It can also be noted that protected and private inheritance does not represent the classic IsA relationship. The following polymorphic behaviour is only possible when inheriting publicly:
Derived d;
Base* b = &d;
However, for private inheritance polymorphic behaviour is possible in the first derived class (but not in subsequent).
struct Base{};
struct Derived : private Base
{
Derived()
{
//IsA holds within member functions of Derived, but not
// outside
Base* b = this;
}
};
struct Derived2 : public Derived
{
Derived2()
{
Base* b = this; //Fails to compile...inaccessible base
}
};
int main()
{
Derived d;
Base* b = &d; //Fails to compile
}
For protected inheritance polymorphic behaviour is possible in the all subsequent derived classes (Therefore code in constructor of Derived2 here above would compile), but not outside of class member functions.
Herb Sutter comments on reasons for using non public inheritance in Uses and abuses.
Finally, a comment concerning your example above: Usually Car would be abstract (an interface, consisting only of pure virtual functions), and therefore it would not contain any data members, but leave it open to the implementation. This is a guideline concerning inheritance that I've heard somewhere Sutter - Exceptional C++:
Inherit publicly in order to be reused by code that uses base classes polymorphically.
Your example would/could become:
struct Car
{
//Note: const used as brandName should not modify logical state.
virtual const std::string& brandName() const = 0;
//...virtual ~Car(), amongst others, depending
// on whether you intend to be deleted via this interface...
};
// Note: public inheritance implied by struct
struct CarFromFile: /*public*/ Car
{
CarFromFile( std::ifstream& file )
: brandName_( strFrom( file ) ),
manufacturer_( strFrom( file )
{
}
virtual const std::string& brandName() const{ return brandName_; }
private:
std::string strFrom( std::ifstream& file )
{
std::string value;
if( file >> value ) { return value; }
throw std::runtime_error( "Invalid file format!" );
}
std::string brandName_;
std::string manufacturer_;
//etc...
};
The fact that you make the accessor abstract, allows freedom from
the perspective of the implementer of derived, and defines the service
required by the client of base, independent of how the actual data looks.
The classifications for public, protected and private are intended to allow one to separate publicly available interfaces from internal implementation details. Thus, things that are not public are inaccessible, forcing users of the class to use the public interfaces provided.
If something is private, then even though inheritance will make the member a part of the derived class, the derivation is not allowed to access it. If it is desirable to allow a derived class access to interfaces and members that are not part of the public interface, then that is exactly when to use protected.