The basic design knowledge, manager is a person, apple is a fruit,
and bla bla bla.
The basic pure virtual, virtual, and non virtual syntax knowledge.
Isolate change between Client and Implement. That is
the high level in design pattern. How to understand interface?
Client<->Interface<->Implement. through Interface, you keep all
the change happen implement side, not affect Client at all.
Public inheritance is substitutability, not to reuse, but to bereused.
About Inheritance, There are three principles.
Liskov Substitution Principle—-Clients (Functions and Class)
that use pointers or references to base classes must be able to use
objects of derived classes without knowing it. So all overrides of
virtual member functions must require less and provide more.
So you can make substitution successfully.
Dependence Inversion Principle. Clients only depends on interface.
Interface segregation principle
Example, see code below. 1)LSP: Car can use GasPower or ElePower
without know it. 2)DIP: Car only is depends on Power* interface 3)ISP:
Interface should be small and separately. An example can be seen in MI
section below.
There are three points:
Pointer or refenence to the base class (Power* pow)
Virtual function support dynamic-binding
You need to design the base class and it should include at least
one virtual function.
More effective 33 "making non-leaf classes abstract" and C++ coding
standards 36 "Prefer providing abstract interfaces." They all said that
you should only inherit from an abstract interfaces. It also follow
DIP.
When you found abstract conception appear in more than onecontext, you need build abstract interface for it.
There are some advantages. use interface will separate client and implement,
make addition and modification implement easier. (But it need good design
at the beginning). If you inherit from concrete base class, It will
cause Slicing problem, Detail can be seen in "ctor in inheritance"
section.
Consider making virtual functions nonpublic, and public function
nonvirtual. This is similar with Template Method design pattern. C++
coding standards Item 39
A common mistake, is inherit from classes that were not designed to be base
class. For example, you want to customize some current class, you have
string class, but you want to change some behavior of string. So you class
myString : public string.
LSP( Liskov Substitution Principle) Functions That use pointers orreferences to base classes must be able to use objects of derivedclasses without knowing it.
client use string class through base class pointer or reference
base class has virtual function.
derived class redefine base class virtual function.
See previous three points: all requirement are not satisfied. Clients most
times use string by value directly, string doesn’t has any virtual function,
it’s a value class, and you didn’t design before hand.
If you want to change find function, You don’t need inherit, Just write
non-member function and pass a string object.
Another mistake is public inheritance is work-like-a, not is-a. For
example, circle is a eclipse, and square is a rectangle, but in oop,
you can’t make circle inherit from eclipse, because, eclipse has two
centers. you can’t make squre inherit from rectangle, because setWidth
is not work as the same as in rectangle, (setWidth in square will
change height at the same time.) It break LSP. A solution is make an
abstract base class(ABC) then make circle and ellipse inherit from
ABC
Previous example also explain, when you design a class, it doesn’t need to
be a practical object, such as animal, car, people, etc. It can be abstract
conception. (So desgin pattern is so important conception).
Composite VS Inheritance:
Does TypeB want to expose the complete interface (all public
methods no less) of TypeA such that TypeB can be used where
TypeA is expected? Indicates Inheritance. e.g. A Cessna biplane
will expose the complete interface of an airplane, if not more. So
that makes it fit to derive from Airplane.
Does TypeB only want only some/part of the behavior exposed
by TypeA? Indicates need for Composition. e.g. A Bird may need
only the fly behavior of an Airplane. In this case, it makes sense to
extract it out as an interface / class / both and make it a member
of both classes.
Inheritance must pass Liskov Substitution Principle. Previous
example about ellipse and circle fail this test. because ellipse has
setLongAxis() and setShortAxis(), but circle doesn’t have them
at all.
No source code, just header and lib, you also can use inheritance in C++
language.
Pure virtual class can’t be instance, it just a abstract interface, it’s
agreement.
Both reference and pointer support polymorphism.
Inheritance three usage: 1) I want to inherit a interface. (pure virtual, you
have to rewrite ) 2) I want to inherit a implement,but I want to change it.
(virtual, you may or maynot rewrite) 3) I want to inherit a implement, but I
don’t want to change it. (Non-virtual, you can’t rewrite it at all)
Sometimes, syntax is right, but it doesn’t mean it is logical or design right.
For example, You can define a virtual function in base class, but if
it’s not pure virtual, A new derived class will inheritance default
implementation. In this way, a better method is make it become pure
virtual. It will oblige all the derive class give it’s own implementation. It
can be thought as strategy pattern, it looks like template method,
but it’s not exactly the same. If two derived class share the same
implementation, you can upgrade the implementation to base class, and
make a protect member function, it make derive class can access
it in it’s own implementation base class pure virtual function. A
practical example can be seen in effective C++ item 36 Airplane
example.