I think I understand the difference between interface and abstract. Abstract sets default behavior and in cases of pure abstract, behavior needs to be set by derived class. Interface is a take what you need without the overhead from a base class. So what is the advantage of interface over composition? The only advantage I can think is use of protected fields in the base class. What am I missing?
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- thread_local variables initialization
- What uses more memory in c++? An 2 ints or 2 funct
相关文章
- List可以存储接口类型的数据吗?
- Class layout in C++: Why are members sometimes ord
- How to mock methods return object with deleted cop
- Which is the best way to multiply a large and spar
- C++ default constructor does not initialize pointe
- Selecting only the first few characters in a strin
- What exactly do pointers store? (C++)
- Converting glm::lookat matrix to quaternion and ba
An interface defines how you will be used.
You inherit in order to be reused. This means you want to fit into some framework. If you don't need to fit into a framework, even one of your own making, don't inherit.
Composition is an implementation detail. Don't inherit in order to get the implementation of the base class, compose it. Only inherit if it allows you to fit into a framework.
Your title does not make sense, and your explanations are a bit blurry, so let's define the terms (and introduce the key missing one).
There are two different things going on here:
Let us start with Interfaces and Abstract Classes.
So, in the context of C++, there is not much difference between either. Especially because the distinction never took into account free-functions.
For example, consider the following "interface":
You can trivially augment it, even with free functions:
In this case, we provide behavior... yet the class itself is still an interface... oh well.
The real debate, therefore, is between Inheritance and Composition.
Inheritance is often misused to inherit behavior. This is bad. Inheritance should be used to model a is-a relationship. Otherwise, you probably want Composition.
Consider the simple use case:
Now, how do we build a
Car
with this ?If you inherit, it will work. However, suddenly you get such code:
Now, if you decide to replace
DieselEngine
withWaterEngine
, the above function does not work. Compilation fails. And havingWaterEngine
inherit fromDieselEngine
certainly feels ikky...What is the solution then ? Composition.
This way, noone can write nonsensical code that assumes that a car is an engine (doh!). And therefore, changing the engine is easy with absolutely no customer impact.
This means that there is less adherence between your implementation and the code that uses it; or as it is usually referred to: less coupling.
The rule of thumb is that in general, inheriting from a class which has data or implement behavior should be frown upon. It can be legitimate, but there are often better ways. Of course, like all rule of thumb, it is to be taken with a grain of salt; be careful of overengineering.
An interface defines behaviour. An abstract class helps to implement behaviour.
In theory there is not a lot of difference between a pure abstract class with no implementation at all, and an interface. Both define an unimplemented API. However, pure abstract classes are often used in languages that don't support interfaces to provide interface like semantics (eg C++).
When you have the choice, generally an abstract base will provide some level of functionality, even if it's not complete. It helps implementation of common behaviour. The downside being you are forced to derive from it. When you are simply defining usage, use an interface. (There's nothing stopping you creating an abstract base that implements an interface).
Interfaces are thin, in C++ they can be described as classes with only pure virtual functions. Thin is good because
This, in conjunction with dynamic library linking, helps facilitate plug and play, one of the unsung but great software innovations of recent times. This leads to greater software interoperability, extensibility etc.
Interfaces can be more work to put in place. Justify their adoption when you have an important subsystem that could have more than one possible implementation, some day. The subsystem should in that case be used through an interface.
Reuse by means of inheiritance requires more knowlegde of the behaviour of the implementation you are overriding so there is greater "coupling". That said it is also a valid approach in cases where interfaces are overkill.
If type Y inherits from type X, then code which knows how to deal with objects of type X will, in most cases, automatically be able to deal with objects of type Y. Likewise, if type Z implements interface I, then code which knows how to use objects about which implement I, without having to know anything about them, will automatically be able to use objects of type Z. The primary purpose of inheritance and interfaces is to allow such substitutions.
By contrast, if object of type P contains an object of type Q, code which expects to work with an object of type Q will not be able to work on one of type P (unless P inherits from Q in addition to holding an object of that type). Code that expects to manipulate an object of type Q will be able to operate on the Q instance contained within P, but only if the code for P explicitly either supplies it to that code directly, or makes it available to outside code which does so.