Module 10 Inheritance and Polymorphism
Module 10 Inheritance and Polymorphism
This module covers two advance topics in object-oriented programming: inheritance and polymorphism.
To continue with the rest of the chapter, please download the zipped Module10_student project file in
OdtuClass and open it in Visual Studio.
1) Inheritance
In object-oriented programming, Inheritance means deriving a new class (called derived class) from an
existing class (called base class). Typically, the base class represents a rather generic object (such as
shape), whereas the derived class (such as rectangle) is a more specialized version of the generic object.
Inheritance relies on “is a relationship” between the derived and base classes. Some examples are:
• A flower is a plant.
• A golden-retriever is a dog.
• A triangle is a shape.
A derived class can have additional properties and methods in addition to those inherited from the base
class. For example, a shape class can have LocationX, LocationY, and Color properties that are common to
all shape objects. A rectangle class derived from the shape class can have properties such as width and
height (that are distinct to a rectangle), in addition to those owned by the base class (e.g., LocationX,
LocationY, and Color).
We will work on an example to understand how inheritance works in practice. Imagine that in our
application we need to create different types of shapes: triangle, rectangle, and circle. All these shapes
share four common properties: an int property named Id, a string property called Name, a string property
called BorderColor, and a string property named FillColor.
Circle class will have three properties in addition to the shared properties: an int property named
Diameter, an int property named Angle, and a double property named Radius. Create a folder named
Model in your project, and inside this folder, create the Circle class file. The definition of the Circle class
is provided below.
class Circle
{
public int Id { get; set; }
public string Name { get; set; }
public string BorderColor { get; set; }
public string FillColor { get; set; }
class Triangle
{
public int Id { get; set; }
public string Name { get; set; }
public string BorderColor { get; set; }
public string FillColor { get; set; }
Rectangle class will have four additional properties: an int property named Width, and an int property
Length. The definition of the Rectangle class is provided below. Add this class to the Model folder.
class Rectangle
{
public int Id { get; set; }
public string Name { get; set; }
public string BorderColor { get; set; }
public string FillColor { get; set; }
You might have already realized that this is a rather inefficient approach. All three classes share four
common properties, and we repeat them in each class. Not only this will result in duplicated code but will
also make it harder to change the common properties or add a new common property.
A more efficient approach would be to define a base class called Shape which will hold all common
properties. Definition of the Shape class is provided below. Add this class to the Model folder.
class Shape
{
public int Id { get; set; }
public string Name { get; set; }
public string BorderColor { get; set; }
public string FillColor { get; set; }
public string DisplayText { get { return Id.ToString() + ". " + Name; } }
}
Now, we will revisit the Triangle, Circle, and Rectangle classes. These classess will derive from the
Shape class (i.e., base class) to inheret the properties shared by all shape objects. Below is the updated
definition of the Triangle class. Please pay attention to the change in the class header. Triangle : Shape.
This format is used to indicate that Triangle derives from the Shape class.
class Triangle : Shape
{
public int Height { get; set; }
public int Base { get; set; }
public int SideLeft { get; set; }
public int SideRight { get; set; }
}
We will also update the Circle and Rectangle classess so that they also derive from the Shape class. In
the updated class definitions, the common properties should be removed.
2) Inheritance in practice
We will put these ideas in practice by working on an application. You should download the project file
from OdtuClass. The interface of the application (see Figure 1) is already created as shown below and
some minimal code is included. This application will allow users to create different shapes, and to list the
shapes created in a list box (available in the Shape List tab page).
When the Create Triangle button is clicked, a new Triangle object should be created (based on the user
input) and shown in the list box inside the Shape List tab page. To implement this, please double click on
the Create Triangle button to create its click event handler.
Inside the click event handler, please write the following code to create an empty Triangle object and
set its property values based on the data provided by the user.
After the object is properly updated with user data, you can use the following code to add this object to
triangles, which is a BindingList type variable defined at class level to hold multiple Triangle type
objects. triangles will be updated each time a new triangle object is created.
Next, the following code will can bind triangles to lst_shapes to list the Triangle objects created.
The DisplayMember property of lst_shapes is set to “DisplayText”, which is a property of the Shape class
that returns the Id and Name properties combined.
Last, what goes inside the click event handler of Create Triangle is the following code. This code will switch
the current tab to Shape List tab where the new objects created are listed. Also, ResetForm method will
be called to reset all the fields to empty.
You can run and test the application. Please enter some data as shown in Figure 4.
We will continue building our application by implementing the Create Rectangle button’s click event
handler (see Figure 6). Please double click on the Create Rectangle button to create its click event handler.
Click event handler of the Create Rectangle button should have a very similar code to what we have
already for the previous button. The main difference would be to create a Rectangle object instead of
Triangle. At this point we can take advantage of Inheritance to somehow avoid writing repetitive code.
To begin with, when creating a new shape (no matter it is a rectangle, triangle, or a circle), it will have four
common properties: Id, Name, BorderColor, and FillColor. All these property values will be set based on
user data. We can define a method that sets the values of these properties for any class object that is
derived from the Shape base class.
Figure 7 shows the definition of the SetSharedProperties method which accepts any Shape object as the
parameter. In this case, Triangle, Rectangle, and Circle objects can be passed as the parameter since each of
them is a shape (as they derive from the Shape class).
Figure 7. Defining the SetSharedProperties method.
Now, we can call this method inside the click event handler of Create Rectangle button. In the code shown
in Figure 8, first a new Rectangle object is created, named myRectangle. Then, SetSharedProperties is
called to set the values for the common properties inherited from the Shape class. Next, the values of the
Width and Length properties are set properly based on user input.
Figure 8. Calling the SetSharedProperties method inside the click event handler.
Now that the object is created and initialized properly, we can display it in the listbox control. As you may
remember, for the Triangle object, we used a BindingList that can hold only Triangle type objects.
However, this is not sufficient because we want to store multiple types of objects in a list and display them
together in a listbox.
We can apply a more effective approach thanks to Inheritance. We will create a BindingList that can hold
Shape type objects. Since triangle, circle, and rectangle are also a shape, they can be stored in this list.
Let’s go ahead and create the BindingList variable, named shapes, to hold Shape type objects. Please
note that this variable should be defined at class level as shown in Figure 9.
Next, we will add the myTriangle object to the shapes list, then we will bind the shapes list to
lst_shapes, as shown below.
//Add the myRectangle object to a list of triangles
shapes.Add(myRectangle);
We need to bind shapes to lst_shapes each time a new Triangle, Circle, or Rectangle objects are
created. We can eliminate this repetition by creating a method that binds shapes list to lst_shapes.
Then, we need to call this method only once when the page is loaded. Since shapes is a BindingList type,
any changes in shapes will be automatically reflected to lst_shapes, where the shapes list is bounded
as the data source. The complete code is shown below.
After these changes, the final code in the click event handler of btn_createRectangle button should
look like this:
Following the same approach, also implement the click event handler for Create Circle (see Figure 12).
Figure 12. Creating click event handler for the Create Circle button.
After completing the click event handlers for buttons, please run your application and add three different
shapes. The list box should be able to display all different types of shapes as shown in Figure 13 below.
Figure 13. Different shapes are added and displayed in the list box.
3) Polymorphism
The term Polymorphism means that objects can exist in different forms. In terms of object-oriented
programming, Polymorphism allows derived classes to have different implementation for the methods
inherited from the base class. Thanks to the polymorphism, program can identify which method to call
depending on the object type. We will apply polymorphism in our current example.
We will add two new methods to the Shape class: CalculatePerimeter and CalculateArea. These
methods will return 0, since the length, width, or diameter of the shape is not known yet.
CalculatePerimeter and CalculateArea methods will have the virtual keyword in the header, as
seen below. Methods declared with virtual keyword are allowed to be overridden by the derived class.
class Shape
{
public int Id { get; set; }
public string Name { get; set; }
public string BorderColor { get; set; }
public string FillColor { get; set; }
Next, we will update the definition of the Rectangle class. As shown below, the Triangle class overrides
the CalculatePerimeter and CalculateArea methods, and provides a new definition for these
methods based on how a triangle’s perimeter and area should be calculated. Pay attention to the
override keyword in the method header. The override indicates that the method in the derived class
overrides a method in the base class.
We will define a new Triangle object, called myTriangle, whose Base is 10 and Height is 15.
We will call the CalculateArea method to calculate the area for the myTriangle object. Then we will
print the computed area using MessageBox.Show method.
The following popup window should appear printing the area of the triangle correctly.
We will update the Circle and Rectangle classes accordingly by overriding the CalculatePerimeter
and CalculateArea methods.
We are allowed to override properties as well. As an additional exercise, you can define the DisplayText
property with virtual keyword, and override this property in the derived classes to set a different display
text for different shapes.
4) Is a relationship in Polymorphism
You may remember that there is a “Is a” relationship between the derived and bases classes. For example,
a Triangle is not only a Triangle but is also a Shape. Thanks to this relationship, we can use a Shape class
variable to reference a Triangle object. For example, look at the following code:
In the code above, a Triangle object is created and assigned to a Shape variable called myShape. This
assignment is legal because a Triangle object is also a Shape object. The CalculateArea method will
compute the area of the triangle correctly because myShape will know that it is referencing a Triangle
object.
5) Polymorphism in practice
We will apply polymorphism in our project to compute the perimeter and area of the item selected in the
list box no matter if it is a triangle, rectangle, or circle. As shown in Figure 15, please double click on the
lst_shapes to create its SelectedIndexChanged event handler.
This event handler will be executed when the selected item in lst_shapes is changed. We will write our
code to compute the perimeter and area of the selected shape inside this event handler. Thanks to
polymorphism this will be quite easy.
First, we obtain the Id of the selected shape by using SelectedValue property. We use the Id value inside
the Single method to find the target shape inside the shapes list . The rest is quite straightforward. We
call the CalculatePerimeter and CalculateArea methods for the shape and print them in the labels
properly. See the complete code in Figure 16.
Please note that, thanks to Inheritance and Polymorphism, the program knows the specific class of each
shape selected (i.e., whether it is a triangle, rectangle, or circle) and calls the correct version of the
CalculatePerimeter and CalculateArea methods depending on the type of the shape.
Please run and test your application. Define different types of shapes and check if the Perimeter and Area
labels are properly updated as these shapes are selected in the list box. Some examples are shown below.