Page d'Accueil

Polymorphism and Abstraction

 

Namespaces and Inheritance

Imagine you had created a class named Person in a namespace named People as follows:

Source File: Persons.cs
using System;

namespace People
{
    public class Person
    {
	private string _name;
	private string _gdr;

	public Person()
	{
	    this._name = "Not Available";
	    this._gdr  = "Unknown";
	}
	public Person(string name, string gender)
	{
	    this._name = name;
	    this._gdr  = gender;
	}

	private string FullName
	{
	    get { return _name; }
	    set { _name = value; }
	}

	private string Gender
	{
	    get { return _gdr; }
	    set { _gdr = value; }
	}
    }
}
 

If you decide to derive a class from it, remember that this class belongs to a namespace. To inherit from this class, the compiler will need to know the namespace in which the class was created. Class inheritance that involves namespaces relies on qualification, like the calling of the members of a namespace. To derive a class from a class member of a namespace, type the name of the namespace, followed by the period operator ".", and followed by the name of the base namespace. Here is an example:

Source File: StaffMembers.cs
using System;

namespace HighSchool
{
	public class Teacher : People.Person
	{
		private string _pos;

		public Teacher()
		{
			this._pos = "Staff Member";
		}

		public Teacher(string pos)
		{
			this._pos     = pos;
		}

		private string Position
		{
			get { return _pos; }
			set { _pos = value; }
		}
	}
}

If you need to call the class that was defined in a different namespace, remember to qualify its name with the period operator. Here is an example:

Source File: Exercise.cs
using System;

class Exercise
{
    static void Main()
    {
	People.Person man = new People.Person("Hermine Sandt", "Male");
	HighSchool.Teacher staff = new HighSchool.Teacher("Vice Principal");

	Console.WriteLine();
    }
}

Alternatively, to use the contents of a namespace, prior to calling a member of that namespace, you can type the using keyword followed by the name of the namespace. Here is an example:

Source File: Exercise.cs
using System;
using People;
using HighSchool;

class Exercise
{
	static void Main()
	{
		Person man = new Person("Hermine Sandt", "Male");
		Teacher staff = new Teacher("Vice Principal");

		Console.WriteLine();
	}
}
 

Practical Learning Practical Learning: Using Inheritance With Namespaces

  1. Start Microsoft Visual C# Express Edition and create a Console Application named Geometry1
  2. To create a new class, on the main menu, click Project -> Add Class...
  3. Set the Name to Square and press Enter
  4. Change the file as follows:
     
    using System;
    
    namespace Geometry1
    {
        public class Square
        {
            private double _side;
    
            public Square()
            {
                _side = 0.00;
            }
    
            public Square(double s)
            {
                _side = s;
            }
        }
    }
  5. To create a new class, on the main menu, click Project -> Add Class...
  6. Set the Name to Rectangle and press Enter
  7. Change the file as follows:
     
    using System;
    
    namespace Geometry1
    {
        public class Rectangle
        {
            double _length;
            double _height;
    
            public Rectangle()
            {
                _length = 0.00;
                _height = 0.00;
            }
    
            public Rectangle(double L, double H)
            {
                _length = L;
                _height = H;
            }
        }
    }
  8. Save all

Protected Members

To maintain a privileged relationship with its children, a parent class can make a set list of members available only to classes derived from it. With this relationship, some members of a parent class have a protected access level. Of course, as the class creator, it is your job to specify this relationship.

To create a member that derived classes only can access, type the protected keyword to its left. Here are examples:

Source File: Persons.cs
using System;

namespace People
{
	public class Person
	{
		private string _name;
		private string _gdr;

		public Person()
		{
			this._name = "Not Available";
			this._gdr    = "Unknown";
		}
		public Person(string name, string gender)
		{
			this._name = name;
			this._gdr  = gender;
		}

		protected string FullName
		{
			get { return _name; }
			set { _name = value; }
		}

		protected string Gender
		{
			get { return _gdr; }
			set { _gdr = value; }
		}
		
		public void Show()
		{
			Console.WriteLine("Full Name: {0}", this.FullName);
			Console.WriteLine("Gender:    {0}", this.Gender);
		}
	}
}

You can access protected members only in derived classes. Therefore, if you instantiate a class outside, you can call only public members:
Source File: Exercise.cs
using System;

class Exercise
{
    static void Main()
    {
	People.Person man = new People.Person("Hermine Sandt", "Male");

	Console.WriteLine("Staff Member");
	man.Show();

	Console.WriteLine();
    }
}

This would produce:

Staff Member
Full Name: Hermine Sandt
Gender:     Male

Virtual Members

We have just mentioned that you can create a new version of a member in a derived class for a member that already exists in the parent class. After doing this, when you call that member in your program, you need to make sure that the right member gets called, the member in the base class or the equivalent member in the derived class.

When you create a base class, if you anticipate that a certain property or method would need to be redefined in the derived class, you can indicate this to the compiler. On the other hand, while creating your classes, if you find out that you are customizing a property of method that already existed in the base class, you should let the compiler know that you are providing a new version. In both cases, the common member should be created as virtual.

To create a virtual member, in the base class, type the virtual keyword to the left of the property or method. Based on this, the Area property of our Circle class can be created as follows:

class Circle
{
	public virtual double Area
	{
		get
		{
			return Radius * Radius * 3.14159;
		}
	}
}

In fact, in C#, unlike C++, if you omit the virtual keyword, the compiler would display a warning.

When you derive a class from an abstract, since the methods (if any) of the abstract class were not implemented, you must implement each one of them in the derived class. When customizing virtual members in a derived class, to indicate that a member is already virtual in the base class and that you are defining a new version, type the override keyword to the left of its declaration. For example, the Area property in our Sphere class can be created as follows:

class Sphere : Circle
{
	public override double  Area
	{
		get
		{
			return 4 * Radius * Radius * 3.14159;
		}
	}

	public double Volume
	{
		get
		{
			return 4 * 3.14159 * Radius * Radius * Radius;
		}
	}
}

In the same way, when implementing an abstract method of a class, type the override keyword to its left.

Practical Learning Practical Learning: Using Virtual Members

  1. To create a new class, on the main menu, click Project -> Add Class...
  2. Set the Name to a ShapeDescription and press Enter
  3. Change the file as follows:
     
    using System;
    
    namespace Geometry1
    {
        public class ShapeDescription
        {
            public virtual string Description()
            {
                string Msg = "A quadrilateral is a geometric figure " +
                             "that has four sides and four angles.";
                return Msg;
            }
        }
    }
  4. Save the file as Quadrilaterals.cs in the Shapes1 folder
  5. Access the Square.cs file and override the Description method as follows:
     
    using System;
    
    namespace Geometry1
    {
        public class Square : ShapeDescription
        {
            private double _side;
    
            public Square()
            {
                _side = 0.00;
            }
    
            public Square(double s)
            {
                _side = s;
            }
    
            public override string Description()
            {
                // Get the introduction from the parent
                string Introduction = base.Description() +
                       "\nA square is a quadrilateral that has four " +
                       "equal sides and four right angles";
    
                return Introduction;
            }
        }
    }
  6. Access Rectangle.cs file and change it as follows:
     
    using System;
    
    namespace Geometry1
    {
        public class Rectangle : ShapeDescription
        {
            double _length;
            double _height;
    
            public Rectangle()
            {
                _length = 0.00;
                _height = 0.00;
            }
    
            public Rectangle(double L, double H)
            {
                _length = L;
                _height = H;
            }
    
            public override string Description()
            {
    
                // Get the introduction from the parent
                string Introduction = base.Description();
    
                string Msg = Introduction +
                       "\nA rectangle is a quadrilateral that has adjacent " +
            "perpendicular sides. This implies that its four " +
                             "angles are right.";
                return Msg;
            }
        }
    }
  7. Access the Program.cs file and change it as follows:
     
    using System;
    
    class Exercise
    {
        static void DisplaySquare(Square S)
        {
    	Console.WriteLine("Square Characteristics");
    	Console.WriteLine("Description: {0}", S.Description());
        }
    
        static void DisplayRectangle(Rectangle R)
        {
    	Console.WriteLine("Rectangle Characteristics");
    	Console.WriteLine("Description: {0}", R.Description());
        }
    
        static void Main()
        {
    	Square Sq = new Square();
    	Rectangle Rect = new Rectangle();
    
    	Console.WriteLine("========================================");
    	DisplaySquare(Sq);
    	Console.WriteLine("========================================");
    	DisplayRectangle(Rect);
    	Console.WriteLine("========================================");
    		
    	Console.WriteLine();
        }
    }
  8. Execute the project. This would produce:
     
    ========================================
    Square Characteristics
    Description: A quadrilateral is a geometric figure that has four sides and four
    angles.
    A square is a quadrilateral that has four equal sides and four right angles
    ========================================
    Rectangle Characteristics
    Description: A quadrilateral is a geometric figure that has four sides and four
    angles.
    A rectangle is a quadrilateral that has adjacent perpendicular sides. This implies 
    that its four angles are right.
    ========================================
  9. Close the DOS window

Abstract Classes

In a program, you can create a class whose role is only meant to provide fundamental characteristics for other classes. This type of class cannot be used to declare a variable. Such a class is referred to as abstract. Therefore, an abstract class can be created only to serve as a parent class for other classes.

To create an abstract class, type the abstract keyword to the left of its name. Here is an example:

abstract class Ball
{
	protected int TypeOfSport;
	protected string Dimensions;
}

Practical Learning Practical Learning: Creating an Abstract Class

  1. To create an abstract class, access the ShapeDescription.cs file and change it as follows:
     
    using System;
    
    namespace Geometry1
    {
        public abstract class ShapeDescription
        {
            public virtual string Description()
            {
                string Msg = "A quadrilateral is a geometric figure " +
                             "that has four sides and four angles.";
                return Msg;
            }
        }
    }
  2. Save the file

Abstract Properties and Methods

When creating a class that would mainly be used as a base for future inheritance, you can create one or more properties and make them abstract. To do this, when creating the property, type the abstract keyword to its left. Because you would not define the property, you can simply type the get keyword and its semi-colon in the body of the property.

A method of a class also can be made abstract. An abstract method can be a member of only an abstract class. If you make a method abstract in a class, you must not implement the method. To create an abstract method, when creating its class, type the abstract keyword to the left of the method's name. End the declaration with a semi-colon and no body for the method since you cannot implement it. Here is an example:

public abstract class Ball
{
	protected int TypeOfSport;
	protected string Dimensions;

	public abstract CalculateArea();
}

In the same way, you can create as many properties and methods as you see fit. You can choose what properties and methods to make abstract. This is important for inheritance.

Practical Learning Practical Learning: Creating an Abstract Property

  1. To create an abstract property, access the ShapeDescription.cs file and change its class as follows:
     
    using System;
    
    namespace Geometry1
    {
        public abstract class ShapeDescription
        {
            public abstract string Name { get; }
    
            public virtual string Description()
            {
                string Msg = "A quadrilateral is a geometric figure " +
                             "that has four sides and four angles.";
                return Msg;
            }
        }
    }
  2. Access the Square.cs file and change it as follows:
     
    using System;
    
    namespace Geometry1
    {
        public class Square : ShapeDescription
        {
            private double _side;
    
            public Square()
            {
                _side = 0.00;
            }
    
            public Square(double s)
            {
                _side = s;
            }
    
            public override string Name
            {
                get { return "Square"; }
            }
    
            public override string Description()
            {
                // Get the introduction from the parent
                string Introduction = base.Description() +
                "\nA square is a quadrilateral that has four " +
                                         "equal sides and four right angles";
    
    
                return Introduction;
            }
        }
    }
  3. Access the Rectangle.cs file and change it as follows:
     
    using System;
    
    namespace Geometry1
    {
        public class Rectangle : ShapeDescription
        {
            double _length;
            double _height;
    
            public Rectangle()
            {
                _length = 0.00;
                _height = 0.00;
            }
    
            public Rectangle(double L, double H)
            {
                _length = L;
                _height = H;
            }
    
            public override string Name
            {
                get { return "Rectangle"; }
            }
    
            public override string Description()
            {
    
                // Get the introduction from the parent
                string Introduction = base.Description();
    
                string Msg = Introduction +
                             "\nA rectangle is a quadrilateral that has adjacent " +
            "perpendicular sides. This implies that its four " +
                             "angles are right.";
                return Msg;
            }
        }
    }
  4. Access the Program.cs file and change it as follows:
     
    using System;
    
    namespace Geometry1
    {
        public class Program
        {
            static void DisplaySquare(Square S)
            {
                Console.WriteLine("Square Characteristics");
                Console.WriteLine("Name:        {0}", S.Name);
                Console.WriteLine("Description: {0}", S.Description());
            }
    
            static void DisplayRectangle(Rectangle R)
            {
                Console.WriteLine("Rectangle Characteristics");
                Console.WriteLine("Name:        {0}", R.Name);
                Console.WriteLine("Description: {0}", R.Description());
            }
    
            static void Main()
            {
                FlatShapes.Square Sq = new FlatShapes.Square();
                FlatShapes.Rectangle Rect = new FlatShapes.Rectangle();
    
                Console.WriteLine("========================================");
                DisplaySquare(Sq);
                Console.WriteLine("========================================");
                DisplayRectangle(Rect);
                Console.WriteLine("========================================");
    
                Console.WriteLine();
            }
        }
    }
  5. Execute the project. This would produce:
     
    ========================================
    Square Characteristics
    Name:        Square
    Description: A quadrilateral is a geometric figure that has four sides and four
    angles. A square is a quadrilateral that has four equal sides and four right angl
    es
    ========================================
    Rectangle Characteristics
    Name:        Rectangle
    Description: A quadrilateral is a geometric figure that has four sides and four
    angles.
    A rectangle is a quadrilateral that has adjacent perpendicular sides. This impli
    es that its four angles are right.
    ========================================
  6. Close the DOS window

Sealed Classes

Any of the classes we have used so far in our lessons can be inherited from. If you create a certain class and don't want anybody to derive another class from it, you can mark it as sealed. In other words, a sealed class is one that cannot serve as base for another class.

To mark a class as sealed, type the sealed keyword to the left of the class keyword. Here is an example:

public sealed class Ball
{
	public int TypeOfSport;
	public string Dimensions;
}

There is not much to do about a sealed class. Simply remember that no class can be derived from it.

 

Home Copyright 2007, Yevol