Reputation: 571
I could not find the main difference. And I am very confused when we could use inheritance and when we can use subtyping. I found some definitions but they are not very clear.
What is the difference between subtyping and inheritance in object-oriented programming?
Upvotes: 37
Views: 22665
Reputation: 263270
If you inherit privately in C++, you get inheritance without subtyping. That is, given:
class Derived : Base // note the missing public before Base
You cannot write:
Base * p = new Derived(); // type error
Because Derived
is not a subtype of Base
. You merely inherited the implementation, not the type.
Upvotes: 8
Reputation: 2954
in a simple word: subtyping and inheritance both are polymorphism, (inheritance is a dynamic polymorphism - overriding). Actually, inheritance is subclassing, it means in inheritance there is no warranty to ensure capability of the subclass with the superclass (make sure subclass do not discard superclass behavior), but subtyping(such as implementing an interface and ... ), ensure the class does not discard the expected behavior.
Upvotes: 1
Reputation: 1291
Subtyping doesn't have to be implemented via inheritance. Some subtyping that is not inheritance:
Upvotes: 1
Reputation: 1340
In addition to the answers already given, here's a link to an article I think is relevant. Excerpts:
In the object-oriented framework, inheritance is usually presented as a feature that goes hand in hand with subtyping when one organizes abstract datatypes in a hierarchy of classes. However, the two are orthogonal ideas.
- Subtyping refers to compatibility of interfaces. A type
B
is a subtype ofA
if every function that can be invoked on an object of typeA
can also be invoked on an object of typeB
.- Inheritance refers to reuse of implementations. A type
B
inherits from another typeA
if some functions forB
are written in terms of functions ofA
.However, subtyping and inheritance need not go hand in hand. Consider the data structure deque, a double-ended queue. A deque supports insertion and deletion at both ends, so it has four functions
insert-front
,delete-front
,insert-rear
anddelete-rear
. If we use justinsert-rear
anddelete-front
we get a normal queue. On the other hand, if we use justinsert-front
anddelete-front
, we get a stack. In other words, we can implement queues and stacks in terms of deques, so as datatypes,Stack
andQueue
inherit fromDeque
. On the other hand, neitherStack
norQueue
are subtypes ofDeque
since they do not support all the functions provided byDeque
. In fact, in this case,Deque
is a subtype of bothStack
andQueue
!
I think that Java, C++, C# and their ilk have contributed to the confusion, as already noted, by the fact that they consolidate both ideas into a single class hierarchy. However, I think the example given above does justice to the ideas in a rather language-agnostic way. I'm sure others can give more examples.
Upvotes: 54
Reputation: 26878
A relative unfortunately died and left you his bookstore.
You can now read all the books there, sell them, you can look at his accounts, his customer list, etc. This is inheritance - you have everything the relative had. Inheritance is a form of code reuse.
You can also re-open the book store yourself, taking on all of the relative's roles and responsibilities, even though you add some changes of your own - this is subtyping - you are now a bookstore owner, just like your relative used to be.
Subtyping is a key component of OOP - you have an object of one type but which fulfills the interface of another type, so it can be used anywhere the other object could have been used.
In the languages you listed in your question - C++, Java and C# - the two are (almost) always used together, and thus the only way to inherit from something is to subtype it and vice versa. But other languages don't necessarily fuse the two concepts.
Upvotes: 16
Reputation: 40633
Inheritance is about gaining attributes (and/or functionality) of super types. For example:
class Base {
//interface with included definitions
}
class Derived inherits Base {
//Add some additional functionality.
//Reuse Base without having to explicitly forward
//the functions in Base
}
Here, a Derived
cannot be used where a Base
is expected, but is able to act similarly to a Base
, while adding behaviour or changing some aspect of Base
s behaviour. Typically, Base
would be a small helper class that provides both an interface and an implementation for some commonly desired functionality.
Subtype-polymorphism is about implementing an interface, and so being able to substitute different implementations of that interface at run-time:
class Interface {
//some abstract interface, no definitions included
}
class Implementation implements Interface {
//provide all the operations
//required by the interface
}
Here, an Implementation
can be used wherever an Interface
is required, and different implementations can be substituted at run-time. The purpose is to allow code that uses Interface
to be more widely useful.
Your confusion is justified. Java, C#, and C++ all conflate these two ideas into a single class hierarchy. However, the two concepts are not identical, and there do exist languages which separate the two.
Upvotes: 8