Related
My program performs some task in a specific manner mentioned by the user.
There are exactly three ways to do the task. The problem is that the three ways, although doing the same job are needed to be implemented using different data structures for various performance boosts at specific places. So, I am performing 3 different classes for each way.
I could write a separate complete procedure for each way, but as I mentioned earlier, they are performing the same task, and so a lot of code repeats, which feels less effective.
What is the best way to write all this?
What I am thinking is of creating another class, say 'Task' base class of these 3 classes containing virtual functions and all. And then according to the user input typecast it to one of the three ways. But, I am not sure how am I going to do this (never did anything close to this).
I found an answer focusing on somewhat same issue- https://codereview.stackexchange.com/a/56380/214758 , but am still not clear with it. I wanted to ask my problem there only, but can't do because of reputation points.
How exactly my blueprint of classes should look like?
EDIT:
PseudoCode for program flow I expect:
class method{......}; //nothing defined just virtual methods
class method1: public method{......};
class method2: public method{......};
class methods: public method{......};
main{/*initialise method object with any of the child class based on user*/
/*run the general function declared in class method and defined in respective class method1/2/3 to perform the task*/}
I can propose the following:
1) Read about polymorphism in c++.
2) In general, read about c++ design patterns.
But for your case, read about Command design pattern.
So,
Instead of casting, use polymorphism:
class Animal
{
virtual void sound() = 0; // abstract
};
class Cat : public Animal
{
virtual void sound(){ printf("Meouuw") }
};
class Dog : public Animal
{
virtual void sound(){ printf("Bauuu") }
};
int main()
{
Animal *pAnimal1 = new Cat(); // pay attention, we have pointer to the base class!
Animal *pAnimal2 = new Dog(); // but we create objects of the child classes
pAnimal1->sound(); // Meouuw
pAnimal2->sound(); // Bauuu
}
You don`t need to cast, when you have the right objects. I hope this helps.
Use command pattern to create different commands, put them e.g. in a queue and execute them ...
So I understand pretty much how it works, but I just can't grasp what makes it useful. You still have to define all the separate functions, you still have to create an instance of each object, so why not just call the function from that object vs creating the object, creating a pointer to the parent object and passing the derived objects reference, just to call a function? I don't understand the benefits of taking this extra step.
Why do this:
class Parent
{
virtual void function(){};
};
class Derived : public Parent
{
void function()
{
cout << "derived";
}
};
int main()
{
Derived foo;
Parent* bar = &foo;
bar->function();
return -3234324;
}
vs this:
class Parent
{
virtual void function(){};
};
class Derived : public Parent
{
void function()
{
cout << "derived";
}
};
int main()
{
Derived foo;
foo.function();
return -3234324;
}
They do exactly the same thing right? Only one uses more memory and more confusion as far as I can tell.
Both your examples do the same thing but in different ways.
The first example calls function() by using Static binding while the second calls it using Dynamic Binding.
In first case the compiler precisely knows which function to call at compilation time itself, while in second case the decision as to which function should be called is made at run-time depending on the type of object which is pointed by the Base class pointer.
What is the advantage?
The advantage is more generic and loosely coupled code.
Imagine a class hierarchy as follows:
The calling code which uses these classes, will be like:
Shape *basep[] = { &line_obj, &tri_obj,
&rect_obj, &cir_obj};
for (i = 0; i < NO_PICTURES; i++)
basep[i] -> Draw ();
Where, line_obj, tri_obj etc are objects of the concrete Shape classes Line, Triangle and so on, and they are stored in a array of pointers of the type of more generalized base class Shape.
This gives the additional flexibility and loose coupling that if you need to add another concrete shape class say Rhombus, the calling code does not have to change much, because it refers to all concrete shapes with a pointer to Base class Shape. You only have to make the Base class pointer point to the new concrete class.
At the sametime the calling code can call appropriate methods of those classes because the Draw() method would be virtual in these classes and the method to call will be decided at run-time depending on what object the base class pointer points to.
The above is an good example of applying Open Closed Principle of the famous SOLID design principles.
Say you want someone to show up for work. You don't know whether they need to take a car, take a bus, walk, or what. You just want them to show up for work. With polymorphism, you just tell them to show up for work and they do. Without polymorphism, you have to figure out how they need to get to work and direct them to that process.
Now say some people start taking a Segway to work. Without polymorphism, every piece of code that tells someone to come to work has to learn this new way to get to work and how to figure out who gets to work that way and how to tell them to do it. With polymorphism, you put that code in one place, in the implementation of the Segway-rider, and all the code that tells people to go to work tells Segway-riders to take their Segways, even though it has no idea that this is what it's doing.
There are many real-world programming analogies. Say you need to tell someone that there's a problem they need to investigate. Their preferred contact mechanism might be email, or it might be an instant message. Maybe it's an SMS message. With a polymorphic notification method, you can add a new notification mechanism without having to change every bit of code that might ever need to use it.
polymorphism is great if you have a list/array of object which share a common ancestor and you wich to do some common thing with them, or you have an overridden method. The example I learnt the concept from, use shapes as and overriding the draw method. They all do different things, but they're all a 'shape' and can all be drawn. Your example doesn't really do anything useful to warrant using polymorphism
A good example of useful polymorphism is the .NET Stream class. It has many implementations such as "FileStream", "MemoryStream", "GZipStream", etcetera. An algorithm that uses "Stream" instead of "FileStream" can be reused on any of the other stream types with little or no modification.
There are countless examples of nice uses of polymorphism. Consider as an example a class that represents GUI widgets. The most base classs would have something like:
class BaseWidget
{
...
virtual void draw() = 0;
...
};
That is a pure virtual function. It means that ALL the class that inherit the Base will need to implement it. And ofcourse all widgets in a GUI need to draw themselves, right? So that's why you would need a base class with all of the functions that are common for all GUI widgets to be defined as pure virtuals because then in any child you will do like that:
class ChildWidget
{
...
void draw()
{
//draw this widget using the knowledge provided by this child class
}
};
class ChildWidget2
{
...
void draw()
{
//draw this widget using the knowledge provided by this child class
}
};
Then in your code you need not care about checking what kind of widget it is that you are drawing. The responsibility of knowing how to draw itself lies with the widget (the object) and not with you. So you can do something like that in your main loop:
for(int i = 0; i < numberOfWidgets; i++)
{
widgetsArray[i].draw();
}
And the above would draw all the widgets no matter if they are of ChildWidget1, ChildWidget2, TextBox, Button type.
Hope that it helps to understand the benefits of polymorphism a bit.
Reuse, generalisation and extensibility.
I may have an abstract class hierarchy like this: Vehicle > Car. I can then simply derive from Car to implement concrete types SaloonCar, CoupeCar etc. I implement common code in the abstract base classes. I may have also built some other code that is coupled with Car. My SaloonCar and CoupeCar are both Cars so I can pass them to this client code without alteration.
Now consider that I may have an interface; IInternalCombustionEngine and a class coupled with with this, say Garage (contrived I know, stay with me). I can implement this interface on classes defined in separate class hierarchies. E.G.
public abstract class Vehicle {..}
public abstract class Bus : Vehicle, IPassengerVehicle, IHydrogenPowerSource, IElectricMotor {..}
public abstract class Car : Vehicle {..}
public class FordCortina : Car, IInternalCombustionEngine, IPassengerVehicle {..}
public class FormulaOneCar : Car, IInternalCombustionEngine {..}
public abstract class PowerTool {..}
public class ChainSaw : PowerTool, IInternalCombustionEngine {..}
public class DomesticDrill : PowerTool, IElectricMotor {..}
So, I can now state that an object instance of FordCortina is a Vehicle, it's a Car, it's an IInternalCombustionEngine (ok contrived again, but you get the point) and it's also a passenger vehicle. This is a powerful construct.
The poly in polymorphic means more than one. In other words, polymorphism is not relevant unless there is more than one derived function.
In this example, I have two derived functions. One of them is selected based on the mode variable. Notice that the agnostic_function() doesn't know which one was selected. Nevertheless, it calls the correct version of function().
So the point of polymorphism is that most of your code doesn't need to know which derived class is being used. The specific selection of which class to instantiate can be localized to a single point in the code. This makes the code much cleaner and easier to develop and maintain.
#include <iostream>
using namespace std;
class Parent
{
public:
virtual void function() const {};
};
class Derived1 : public Parent
{
void function() const { cout << "derived1"; }
};
class Derived2 : public Parent
{
void function() const { cout << "derived2"; }
};
void agnostic_function( Parent const & bar )
{
bar.function();
}
int main()
{
int mode = 1;
agnostic_function
(
(mode==1)
? static_cast<Parent const &>(Derived1())
: static_cast<Parent const &>(Derived2())
);
}
Polymorphism is One of the principles OOP. With polymorphism you can choose several behavior in runtime. In your sample, you have a implementation of Parent, if you have more implementation, you can choose one by parameters in runtime. polymorphism help for decoupling layers of application. in your sample of third part use this structers then it see Parent interface only and don't know implementation in runtime so third party independ of implementations of Parent interface. You can see Dependency Injection pattern also for better desing.
Just one more point to add. Polymorphism is required to implement run-time plug-ins. It is possible to add functionality to a program at run-time. In C++, the derived classes can be implemented as shared object libraries. The run time system can be programmed to look at a library directory, and if a new shared object appears, it links it in and can start to call it. This can also be done in Python.
Let's say that my School class has a educate() method. This method accepts only people who can learn. They have different styles of learning. Someone grasps, someone just mugs it up, etc.
Now lets say I have boys, girls, dogs, and cats around the School class. If School wants to educate them, I would have to write different methods for the different objects, under School.
Instead, the different people Objects (boys,girls , cats..) implement the Ilearnable interface. Then, the School class does not have to worry about what it has to educate.
School will just have to write a
public void Educate (ILearnable anyone)
method.
I have written cats and dogs because they might want to visit different type of school. As long as it is certain type of school (PetSchool : School) and they can Learn, they can be educated.
So it saves multiple methods that have the same implementation but different input types
The implementation matches the real life scenes and so it's easy for design purposes
We can concentrate on part of the class and ignore everything else.
Extension of the class (e.g. After years of education you come to know, hey, all those people around the School must go through GoGreen program where everyone must plant a tree in the same way. Here if you had a base class of all those people as abstract LivingBeings, we can add a method to call PlantTree and write code in PlantTree. Nobody needs to write code in their Class body as they inherit from the LivingBeings class, and just typecasting them to PlantTree will make sure they can plant trees).
i want to implement an Algorithm class which uses some utility classes.
but one class may need member variable or function of other utility class. So instead of
composition is it better to use inheritance as below ?
class A{
public:
void setA(int var){ a = var;}
int a;
};
class B{
public:
void foo(int var){
if (var==1){
//bla bla...
}else{
//bik bik...
}
};
class Algo : public A , public B{
public :
void run(){
setA(1);
foo(a);
}
};
Your class Algo should only inherit from A and B if it is a true IS-A relationship to A and B. If you are just wanting to use functionality from A or B, consider composition instead (or at least private inheritance).
For example, if I want to create a class, and that class needs to do some logging, then my class HAS-A logger, but it's not the case that it IS-A logger. Thus I wouldn't want to inherit from logger, but use composition instead.
In your case it doesn't make sense to use inheritance because Algo isn't a A or B, it merely uses them.
Inheritance is meant to express an "is a" relationship and should adhere to the Liskov substitution principle. Can you say Algo is an A and Algo is a B? In general I feel it's a bad idea for a derived class to muck with the base classes private variables (you may set them as protected but they should probably be private). You can always write getters and setters. You can get into trouble with multiple inheritance in so many ways and I think your approach while convenient now will lead you to program in a less maintainable way. I try to reserve inheritance for when I need to treat classes polymorphically, in most other cases I prefer composition.
I like this concept of inheritance:
Commonly thought of as a way to "reuse existing code" by creating a new class that inherits from another existing class. This way you can extend the functionality of an existing class w/o touching the existing class's code. But Herb Sutter has a bit of a different take on the use of inheritance--"Inherit, not to reuse, but to be reused. Don't inherit publicly to reuse code (that exists in the base class); inherit publicly in order to be reused (by existing code that already uses base objects polymorphically)." [C++ Coding Standards, p. 64]. He also says "In correct inheritance, a derived class models a special case of a more general base concept." [ibid, p. 66]
http://cpp.strombergers.com/
so if you don't need to reuse code polymorphically, or to make more special case for base, better use a composition.
Don't pick inheritance over composition as long as you do not need polymorphism. In your case, as you don't have and virtual functions in classes A and B that needs to be changed in class Algo, composition may be a better design choice.
If I want to make a class adaptable, and make it possible to select different algorithms from the outside -- what is the best implementation in C++?
I see mainly two possibilities:
Use an abstract base class and pass concrete object in
Use a template
Here is a little example, implemented in the various versions:
Version 1: Abstract base class
class Brake {
public: virtual void stopCar() = 0;
};
class BrakeWithABS : public Brake {
public: void stopCar() { ... }
};
class Car {
Brake* _brake;
public:
Car(Brake* brake) : _brake(brake) { brake->stopCar(); }
};
Version 2a: Template
template<class Brake>
class Car {
Brake brake;
public:
Car(){ brake.stopCar(); }
};
Version 2b: Template and private inheritance
template<class Brake>
class Car : private Brake {
using Brake::stopCar;
public:
Car(){ stopCar(); }
};
Coming from Java, I am naturally inclined to always use version 1, but the templates versions seem to be preferred often, e.g. in STL code? If that's true, is it just because of memory efficiency etc (no inheritance, no virtual function calls)?
I realize there is not a big difference between version 2a and 2b, see C++ FAQ.
Can you comment on these possibilities?
This depends on your goals. You can use version 1 if you
Intend to replace brakes of a car (at runtime)
Intend to pass Car around to non-template functions
I would generally prefer version 1 using the runtime polymorphism, because it is still flexible and allows you to have the Car still have the same type: Car<Opel> is another type than Car<Nissan>. If your goals are great performance while using the brakes frequently, i recommend you to use the templated approach. By the way, this is called policy based design. You provide a brake policy. Example because you said you programmed in Java, possibly you are not yet too experienced with C++. One way of doing it:
template<typename Accelerator, typename Brakes>
class Car {
Accelerator accelerator;
Brakes brakes;
public:
void brake() {
brakes.brake();
}
}
If you have lots of policies you can group them together into their own struct, and pass that one, for example as a SpeedConfiguration collecting Accelerator, Brakes and some more. In my projects i try to keep a good deal of code template-free, allowing them to be compiled once into their own object files, without needing their code in headers, but still allowing polymorphism (via virtual functions). For example, you might want to keep common data and functions that non-template code will probably call on many occasions in a base-class:
class VehicleBase {
protected:
std::string model;
std::string manufacturer;
// ...
public:
~VehicleBase() { }
virtual bool checkHealth() = 0;
};
template<typename Accelerator, typename Breaks>
class Car : public VehicleBase {
Accelerator accelerator;
Breaks breaks;
// ...
virtual bool checkHealth() { ... }
};
Incidentally, that is also the approach that C++ streams use: std::ios_base contains flags and stuff that do not depend on the char type or traits like openmode, format flags and stuff, while std::basic_ios then is a class template that inherits it. This also reduces code bloat by sharing the code that is common to all instantiations of a class template.
Private Inheritance?
Private inheritance should be avoided in general. It is only very rarely useful and containment is a better idea in most cases. Common case where the opposite is true when size is really crucial (policy based string class, for example): Empty Base Class Optimization can apply when deriving from an empty policy class (just containing functions).
Read Uses and abuses of Inheritance by Herb Sutter.
The rule of thumb is:
1) If the choice of the concrete type is made at compile time, prefer a template. It will be safer (compile time errors vs run time errors) and probably better optimized.
2) If the choice is made at run-time (i.e. as a result of a user's action) there is really no choice - use inheritance and virtual functions.
Other options:
Use the Visitor Pattern (let external code work on your class).
Externalize some part of your class, for example via iterators, that generic iterator-based code can work on them. This works best if your object is a container of other objects.
See also the Strategy Pattern (there are c++ examples inside)
Templates are a way to let a class use a variable of which you don't really care about the type. Inheritance is a way to define what a class is based on its attributes. Its the "is-a" versus "has-a" question.
Most of your question has already been answered, but I wanted to elaborate on this bit:
Coming from Java, I am naturally
inclined to always use version 1, but
the templates versions seem to be
preferred often, e.g. in STL code? If
that's true, is it just because of
memory efficiency etc (no inheritance,
no virtual function calls)?
That's part of it. But another factor is the added type safety. When you treat a BrakeWithABS as a Brake, you lose type information. You no longer know that the object is actually a BrakeWithABS. If it is a template parameter, you have the exact type available, which in some cases may enable the compiler to perform better typechecking. Or it may be useful in ensuring that the correct overload of a function gets called. (if stopCar() passes the Brake object to a second function, which may have a separate overload for BrakeWithABS, that won't be called if you'd used inheritance, and your BrakeWithABS had been cast to a Brake.
Another factor is that it allows more flexibility. Why do all Brake implementations have to inherit from the same base class? Does the base class actually have anything to bring to the table? If I write a class which exposes the expected member functions, isn't that good enough to act as a brake? Often, explicitly using interfaces or abstract base classes constrain your code more than necessary.
(Note, I'm not saying templates should always be the preferred solution. There are other concerns that might affect this, ranging from compilation speed to "what programmers on my team are familiar with" or just "what I prefer". And sometimes, you need runtime polymorphism, in which case the template solution simply isn't possible)
this answer is more or less correct. When you want something parametrized at compile time - you should prefer templates. When you want something parametrized at runtime, you should prefer virtual functions being overridden.
However, using templates does not preclude you from doing both (making the template version more flexible):
struct Brake {
virtual void stopCar() = 0;
};
struct BrakeChooser {
BrakeChooser(Brake *brake) : brake(brake) {}
void stopCar() { brake->stopCar(); }
Brake *brake;
};
template<class Brake>
struct Car
{
Car(Brake brake = Brake()) : brake(brake) {}
void slamTheBrakePedal() { brake.stopCar(); }
Brake brake;
};
// instantiation
Car<BrakeChooser> car(BrakeChooser(new AntiLockBrakes()));
That being said, I would probably NOT use templates for this... But its really just personal taste.
Abstract base class has on overhead of virtual calls but it has an advantage that all derived classes are really base classes. Not so when you use templates – Car<Brake> and Car<BrakeWithABS> are unrelated to each other and you'll have to either dynamic_cast and check for null or have templates for all the code that deals with Car.
Use interface if you suppose to support different Break classes and its hierarchy at once.
Car( new Brake() )
Car( new BrakeABC() )
Car( new CoolBrake() )
And you don't know this information at compile time.
If you know which Break you are going to use 2b is right choice for you to specify different Car classes. Brake in this case will be your car "Strategy" and you can set default one.
I wouldn't use 2a. Instead you can add static methods to Break and call them without instance.
Personally I would allways prefer to use Interfaces over templates because of several reasons:
Templates Compiling&linking errors are sometimes cryptic
It is hard to debug a code that based on templates (at least in visual studio IDE)
Templates can make your binaries bigger.
Templates require you to put all its code in the header file , that makes the template class a bit harder to understand.
Templates are hard to maintained by novice programmers.
I Only use templates when the virtual tables create some kind of overhead.
Ofcourse , this is only my self opinion.
In a project our team is using object lists to perform mass operations on sets of data that should all be processed in a similar way. In particular, different objects would ideally act the same, which would be very easily achieved with polymorphism. The problem I have with it is that inheritance implies the is a relationship, rather than the has a relationship. For example, several objects have a damage counter, but to make this easy to use in an object list, polymorphism could be used - except that would imply an is a relationship which wouldn't be true. (A person is not a damage counter.)
The only solution I can think of is to have a member of the class return the proper object type when implicitly casted instead of relying on inheritance. Would it be better to forgo the is a / has a ideal in exchange for ease of programming?
Edit:
To be more specific, I am using C++, so using polymorphism would allow the different objects to "act the same" in the sense that the derived classes could reside within a single list and be operated upon by a virtual function of the base class. The use of an interface (or imitating them via inheritance) seems like a solution I would be willing to use.
I think you should be implementing interfaces to be able to enforce your has a relationships (am doing this in C#):
public interface IDamageable
{
void AddDamage(int i);
int DamageCount {get;}
}
You could implement this in your objects:
public class Person : IDamageable
public class House : IDamageable
And you'd be sure that the DamageCount property and has a method to allow you to add damage, without implying that a person and a house are related to each other in some sort of heirarchy.
This can be accomplished using multiple inheritance. In your specific case (C++), you can use pure virtual classes as interfaces. This allows you to have multiple inheritance without creating scope/ambiguity problems. Example:
class Damage {
virtual void addDamage(int d) = 0;
virtual int getDamage() = 0;
};
class Person : public virtual Damage {
void addDamage(int d) {
// ...
damage += d * 2;
}
int getDamage() {
return damage;
}
};
class Car : public virtual Damage {
void addDamage(int d) {
// ...
damage += d;
}
int getDamage() {
return damage;
}
};
Now both Person and Car 'is-a' Damage, meaning, they implement the Damage interface. The use of pure virtual classes (so that they are like interfaces) is key and should be used frequently. It insulates future changes from altering the entire system. Read up on the Open-Closed Principle for more information.
I agree with Jon, but assuming you still have need for a separate damage counter class, you can do:
class IDamageable {
virtual DamageCounter* damage_counter() = 0;
};
class DamageCounter {
...
};
Each damageable class then needs to provide their own damage_counter() member function. The downside of this is that it creates a vtable for each damageable class. You can instead use:
class Damageable {
public:
DamageCounter damage_counter() { return damage_counter_; }
private:
DamageCounter damage_counter_;
};
But many people are Not Cool with multiple inheritance when multiple parents have member variables.
Sometimes it's worth giving up the ideal for the realistic. If it's going to cause a massive problem to "do it right" with no real benefit, then I would do it wrong. With that said, I often think it's worth taking the time to do it right, because unnecessary multiple inheritance increases complexity, and it can contribute to the system being less maintainable. You really have to decide what's best for your circumstance.
One option would be to have these objects implement a Damageable interface, rather than inheriting from DamageCounter. This way, a person has-a damage counter, but is damageable. (I often find interfaces make a lot more sense as adjective than nouns.) Then you could have a consistent damage interface on Damageable objects, and not expose that a damage counter is the underlying implementation (unless you need to).
If you want to go the template route (assuming C++ or similar), you could do this with mixins, but that can get ugly really quickly if done poorly.
This question is really confusing :/
Your question in bold is very open-ended and has an answer of "it depends", but your example doesn't really give much information about the context from which you are asking. These lines confuse me;
sets of data that should all be processed in a similar way
What way? Are the sets processed by a function? Another class? Via a virtual function on the data?
In particular, different objects would ideally act the same, which would be very easily achieved with polymorphism
The ideal of "acting the same" and polymorphism are absolutely unrelated. How does polymorphism make it easy to achieve?
#Kevin
Normally when we talk about 'is a' vs 'has a' we're talking about Inheritance vs Composition.
Um...damage counter would just be attribute of one of your derived classes and wouldn't really be discussed in terms of 'A person is a damage counter' with respect to your question.
Having the damage counter as an attribute doesn't allow him to diverse objects with damage counters into a collection. For example, a person and a car might both have damage counters, but you can't have a vector<Person|Car> or a vector<with::getDamage()> or anything similar in most languages. If you have a common Object base class, then you can shove them in that way, but then you can't access the getDamage() method generically.
That was the essence of his question, as I read it. "Should I violate is-a and has-a for the sake of treating certain objects as if they are the same, even though they aren't?"
Normally when we talk about 'is a' vs 'has a' we're talking about Inheritance vs Composition.
Um...damage counter would just be attribute of one of your derived classes and wouldn't really be discussed in terms of 'A person is a damage counter' with respect to your question.
See this:
http://www.artima.com/designtechniques/compoinh.html
Which might help you along the way.
#Derek: From the wording, I assumed there was a base clase, having re-read the question I kinda now see what he's getting at.
"Doing it right" will have benefits in the long run, if only because someone maintaining the system later will find it easier to comprehend if it was done right to begin with.
Depending on the language, you may well have the option of multiple inheritance, but normally simple interfaces make the most sense. By "simple" I mean make an interface that isn't trying to be too much. Better to have lots of simple interfaces and a few monolithic ones. Of course, there is always a trade off, and too many interfaces would probably lead to ones being "forgotten" about...
#Andrew
The ideal of "acting the same" and polymorphism are absolutely unrelated. How does polymorphism make it easy to achieve?
They all have, e.g., one function in common. Let's call it addDamage(). If you want to do something like this:
foreach (obj in mylist)
obj.addDamage(1)
Then you need either a dynamic language, or you need them to extend from a common parent class (or interface). e.g.:
class Person : DamageCounter {}
class Car : DamageCounter {}
foreach (DamageCounter d in mylist)
d.addDamage(1)
Then, you can treat Person and Car the same in certain very useful circumstances.
Polymorphism does not require inheritance. Polymorphism is what you get when multiple objects implement the same message signature (method).