C# Polymorphism and Inheritance override the abstract or virtual

By admin - Last updated: Sunday, February 1, 2009 - Save & Share - Leave a Comment

Occasionally, programmers get to explain Polymorphism and Inheritance in .NET, I’ve compiled some typical use cases in case they need to be explained without IDE.
We start with

Here is class diagram for above.

polymorphism

polymorphism

Let’s see the code,
Declare a variable case1 of type IDrawable and initialize case1 Rect, in other words, An IDrawable variable case1 stores the address of Rect object in the memory.

IDrawable case1 = new Rect();
            case1.Draw();
            Out.WriteLine(Environment.NewLine);
            // output:
            // Draw Shape Called
            // Draw Rect Called

            // IDrawable doesn't see the new implementation
            // from Square but it knows the concrete
            // implementation in Rect because of the override
            case1 = new Square();
            case1.Draw();
            // output:
            // Draw Shape Called
            // Draw Rect Called

            // Shape type cannot see it either but
            // it knows the concrete implementation
            (case1 as Shape).Draw();
            // output: same as above

            // Geometry type cannot see it either but
            // it knows the concrete implementation
            (case1 as Geometry).Draw();
            // output: same as above
 

The two outputs are identical, the reason Draw() in Square is not being called is the concrete implementation of Draw() has been done within Rect for type IDrawable and the sealed indicates there wouldn’t be any more implementation from its sub class for IDrawable. However, we do see Draw() has an implementation in Square, this Draw() actually hides the method in the supper class Shape, but the hiding wouldn’t take place unless the variable type sees the new Draw() implementation. For example, the type of Square or its derived classes. In this case the following code will produce the result. Again this is because Square and its sub classes all see the new implementation of Draw().

// cast it to Square type,
            // then it sees the new Draw() implementation
            (case1 as Square).Draw();
            // output:
            // Draw Shape Called
            // Draw Rect Called
            // Draw Square Called

            // Square type sees the new Draw()
            Square case11 = new Square();
            case11.Draw();
            // output: same as above

            // Square type  sees the new Draw()
            case11 = new FilledSquare();
            case11.Draw();
            // output: same as above

           // FilledSquare type  sees the new Draw() in itself and its parent
            FilledSquare case12 = new FilledSquare();
            case12.Draw();
            // output:
            // Draw Shape Called
            // Draw Rect Called
            // Draw Square Called
            // Draw FilledSquare Called
 

override provides a concrete implementation for either virtual or abstract method in its super class, the variable type always looks for the closest concrete implementation within the initialized object.

The sealed keyword prevents any more concrete implementation from its derived classes so that it ensures the method behavior for the variable type.
In order to use your own implementation even when the supper method is already sealed override, you have to use a variable type which sees the new implementation.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Out = System.Console;

namespace Polymorphism
{
    /// <summary>
    /// Represents IDrawable interface
    /// </summary>
    public interface IDrawable
    {
        void Draw();
    }

    /// <summary>
    /// Represents abstract Geometry class
    /// </summary>
    public abstract class Geometry : IDrawable
    {
        public abstract void Draw();
        public void PrintType()
        {
            Out.WriteLine(this.GetType().Name);
        }
    }

    /// <summary>
    /// Represents Shape class
    /// </summary>
    public class Shape : Geometry
    {
        public override void Draw()
        {
            base.PrintType();
            Out.WriteLine("Draw Shape Called");
        }
    }

    /// <summary>
    /// Represents Rect class
    /// </summary>
    public class Rect : Shape
    {
        public sealed override void Draw()
        {
            base.Draw();
            Out.WriteLine("Draw Rect Called");
        }
    }

    /// <summary>
    /// Represents Square class
    /// </summary>
    public class Square : Rect
    {
        public new void Draw()
        {
            base.Draw();
            Out.WriteLine("Draw Square Called");
        }
    }

    /// <summary>
    /// Represents FilledSquare class
    /// </summary>
    public class FilledSquare : Square
    {
        public new void Draw()
        {
            base.Draw();
            Out.WriteLine("Draw FilledSquare Called");
        }
    }
}

Download polymorphism solution




Posted in Code Notes • Tags: , , Top Of Page

Write a comment


Captcha: 1 + = two