Inheritance & Polymorphism - C# Programming for Beginners (2015)

C# Programming for Beginners (2015)

Chapter 8: Inheritance & Polymorphism

In the last two chapters, we covered basic object oriented concepts (OOP). In this chapter, we are going to study two advanced OOPs: Inheritance and Polymorphism. Like all the other OOP concepts, inheritance in OOP is similar to the concept of real world inheritance. A child inherits some of the traits of his/her parents while also having some traits specific to him/her. In object oriented programming, the concept is similar. Inheritance also exists between different classes and is marked by an Is-A relationship. For instance, a “laptop” is a product, a “car” is a vehicle, and an “employee” is a person. Here, “laptop” is a child class of product, “car” is child of vehicle, and “employee” is a child class of person. The concept of polymorphism is based on inheritance; we will study that in a later section.

Contents

· Inheritance

· Polymorphism

1- Inheritance

The idea of inheritance is that all the traits that are common between the child classes are implemented in the parent class, while traits that are specific to individual child classes are implemented in the respective child classes. For instance, take a parent product class and its child software and hardware product. Both software and hardware products have a name and price. Therefore, we can include both name and price properties in the parent product class. Classes that inherit the parent class have all the attributes of the parent class by default. However, software has no weight while hardware product has some weight. This means that the attribute weight is unique to hardware class; therefore, it cannot be implemented in the parent class. Similarly, we assume that software has a version number while hardware has no version number. Here, version is unique to the software class and cannot be implemented in the parent class. This scenario has been implemented in Example1.

Example1:

Add three classes(Product, Hardware, and Software) to your project. The code markup of these three classes should be as follows:

Product.cs

using System;

namespaceMyCSharpApplication

{

class Product

{

public string name;

public int price;

}

}

In the Product class, we added only two attributes: name and price.

Software.cs

using System;

namespaceMyCSharpApplication

{

class Software : Product

{

publicint version;

public Software(string name, int price, int version)

{

this.name = name;

this.price = price;

this.version = version;

}

}

}

Have a look at the declaration of the software class. After the name of the class, we appended a semicolon followed by “Product”. This is how the child class inherits the parent class. You have to append a semicolon after the child class name followed by the class name which you want your child class to inherit. In the above code, the “Software” class is inheriting the “Product” class. In the software classes, we added only one attribute named “version”. Then we added a parameterized constructor with three parameters. Inside the constructor, we initialized name, price, and version attributes. Notice that the “Software” class doesn’t contain name and price attributes, but since it is inheriting the “Product” class, which contains these attributes, the child “Software” class has these attributes by default. In the same way, we inherited the “Hardware” class from the “Product” class and initialized its attributes.

Hardware.cs

using System;

namespaceMyCSharpApplication

{

class Hardware : Product

{

publicint weight;

public Hardware(string name, int price, int weight)

{

this.name = name;

this.price = price;

this.weight = weight;

}

}

}

In the “Program” class, we create objects of both the “Software” and “Hardware” classes using their parameterized constructors and then display the names of both of the objects.

Program.cs

using System;

namespaceMyCSharpApplication

{

class Program

{

static void Main(string[] args)

{

Software s = new Software("windows 7", 150, 3);

Hardware h = new Hardware("Laptop", 500, 2);

Console.WriteLine("You bought: " + s.name + " and " + h.name);

Console.Read();

}

}

}

Output1:

You bought: windows 7 and Laptop

2- Polymorphism

The object of the parent class can hold objects of child classes. The parent class acts differently depending on the reference of the object it is storing. This concept lies in the basis of polymorphism. Suppose the “Product” class has a method, “DisplayProduct”, which displays the name of the product on screen. Both the child classes also have a method called “DisplayProduct”. The method inside the “Software” class displaysname and version while the method inside the “Hardware” class displays name and price. Since the object of the “Product” class can store references of the “Product”, “Software”, and “Hardware” classes, the question arises here that if “DisplayProduct” method is called on the object, which method will be called? Will it be of “Product”, “Software”, or “Hardware” class? The answer is the “DisplayProduct” method will call the class whose reference is stored in the object of the “Product” class. This concept has been explained in Example2.

Example2

Make the following modification to the “Product”, “Software”, and “Hardware” classes added in Example1.

Product.cs

using System;

namespaceMyCSharpApplication

{

class Product

{

public string name;

public int price;

public virtual void DisplayProduct()

{

Console.WriteLine("This is a parent class: " + name);

}

}

}

If child classes have to contain a method with the same name as in the parent class, that method has to be marked virtual in the parent class. This is why we marked the “DisplayProduct” method virtual in the parent class. When this method is added in the child class, it has to be marked with the keyword “override”. This is shown in both the “Software” and “Hardware” classes.

Software.cs

using System;

namespaceMyCSharpApplication

{

class Software : Product

{

publicint version;

public Software(string name, int price, int version)

{

this.name = name;

this.price = price;

this.version = version;

}

public override void DisplayProduct()

{

Console.WriteLine("You bought " + name + ", version "+ version);

}

}

}

Hardware.cs

using System;

namespaceMyCSharpApplication

{

class Hardware : Product

{

publicint weight;

public Hardware(string name, int price, int weight)

{

this.name = name;

this.price = price;

this.weight = weight;

}

public override void DisplayProduct()

{

Console.WriteLine("You bought " + name + ", weight " + weight);

}

}

}

In the “Program” class, we created the object of parent “Product” class and then stored references of the objects of the “Product”, “Software”, and “Hardware” classes in it. Then we called the “DisplayProduct” method sequentially. You will see that, in the output, different “DisplayProduct” methods will be called depending on the references stored in the “Product” class object.

Program.cs

using System;

namespaceMyCSharpApplication

{

class Program

{

static void Main(string[] args)

{

Product p = new Product();

p.name = "Apple";

p.price = 10;

p.DisplayProduct();

p = new Software("windows 7", 150, 3);

p.DisplayProduct();

p = new Hardware("Laptop", 500, 2);

p.DisplayProduct();

Console.Read();

}

}

}

Output2:

This is a parent class: Apple

You bought windows 7, version 3

You bought Laptop, weight 2

Exercise 8

Task:

Create a class named “Shape”. Add one member variable, “name”, to this class. Add a method called “DisplayName” which displays the variable name on console screen with the appropriate statement. Create two classes, “Triangle” and “Pentagon”. Create parameterized constructors which initialize variable names in both the “Triangle” and “Pentagon” classes. These classes will implement their own “DisplayName” method. Using a test class, such as Program.cs, show how polymorphism can be achieved in this scenario.

Solution:

Shape Class:

using System;

namespaceMyCSharpApplication

{

class Shape

{

public string name;

public virtual void DisplayName()

{

Console.WriteLine("This is a parent class named: " + name);

}

}

}

Triangle Class

using System;

namespaceMyCSharpApplication

{

class Triangle: Shape

{

public Triangle (string name)

{

this.name = name;

}

public override void DisplayName()

{

Console.WriteLine ("This is a child class named: " + name);

}

}

}

Pentagon Class

using System;

namespaceMyCSharpApplication

{

class Pentagon: Shape

{

public Pentagon (string name)

{

this.name = name;

}

public override void DisplayName()

{

Console.WriteLine ("This is a child class named: " + name);

}

}

}

}

Program Class

using System;

namespaceMyCSharpApplication

{

class Program

{

static void Main(string[] args)

{

Shape s = new Shape();

s.name = "Shape";

s.DisplayName();

s = new Triangle("Triangle");

s.DisplayName();

s = new Pentagon("Pentagon");

s.DisplayName();

Console.Read();

}

}

}