I would say the hardest part is deciding when it's useful. Polymorphism is (if you understand parent and child classes ) passing a child class as a pointer to the parent.
You may have seen this type of example, but I'm going to do it just in case you haven't.
Code: Select all
class Animal
{
// list functions that all animals can do
void Speak();
char *says;
};
class Dog : public Animal // This is how Dog becomes a child of Animal
{
// List function that only Dogs do
void DigHole( int depth );
};
class Cat : public Animal
{
void RetractClaws();
};
int GetAge( Animal *pPet )
{
return pPet->GetAge()
}
void main()
{
Dog bullDog;
Cat tabby;
// Here's one way how to use polymorphism
Animal **pet = new Animal*[2];
pet[0] = &bullDog;
pet[1] = &tabby;
for(int i = 0; i < 2; i++)
{
pet[ i ]->Speak();
}
// Here's another way
Animal **pets = new Animal*[2];
pets[0] = new Dog();
pets[1] = new Cat();
// And another way
int dogAge = GetAge( &Dog );
}
The problem then arises that as long as the functions and data you need is in the parent class such as the Speak() function, everything is fine, but when you need to access functions or data that is only in the child classes, you would actually need to have either a Dog pointer or a Dog object and call the required function such as the DigHole function.
Here's my advice.
- Make a basic program that draws a box. The box will need a position, color and size.
- Make this program using the information you have learned. Look for things that belong together like boxHeight, boxWidth and so on.
- Group all those things into a class, call it class Box.
- Next, have your computer draw a triangle. Triangle has height, width, position, color. You will notice they share some of the same properties, biggest difference is the number of points in each and how things like area are calculated. Since both share the same types of data you could save time by creating parent/child classes.
- Create a class called Shape. Parent this class with the Box and Triangle classes like the example above.
- Move your position variables to the Shape class and remove them from both the other two classes. If done correctly, this shouldn't keep your code from running providing your program ran before this step. Now say you wanted to find the area of the shape. Both shapes have an area, but are computed differently so we can't just put a function in Shape. We could write a ( int BoxArea() ) function and a ( int TriangleArea() ) function, but then your Box will have that function as well, and Box doesn't need to calculate the area of a triangle. Remember, you can't call a function from the child class if the object has been morphed to be a parent class pointer.
- Make a function called Area in the Shape class and have it return an int.
- Add the word "virtual" to the front of it and the word "abstract" a the end of it before the ";". This gives us the function that the child classes will be able to use even if morphed into a parent pointer. The "abstract" at the end means that the class cannot be created, so Shape myShape; won't work. It's just a "heads up" to the compiler that a child class has a definition for the function, use it.
- Make the function "int Area() override" in the two child classes. The name, the parameter list and the return type have to match the virtual function from the parent class.
- Define the function for finding the areas of both the triangle and the box. Make sure to remember to have it return the result.
- Now create a function in Game that returns an int and takes a Shape* shape as the parameter.
From here you can build on this. For example, both shapes need to be drawn, you could make a draw functions, add other shapes etc. At this point you want to experiment and see what else you can do with polymorphism. The best uses I can think of for polymorphism is; 1) you can put them in a loop and write something like
Code: Select all
for( int i = 0; i < nShapes; i++)
{
int shapeArea = shape[ i ].Area();
}
instead of writing out a call to each shape's area function.
2) You can pass them into functions that take a base pointer no matter which child it is, so you don't have to write so many functions.
Code: Select all
bool CompareSizes( Shape *A, Shape *B )
{
return A->Area() == B->Area();
}