Demonstration of inheritance with some shapes I had a job interview take home test where I was asked a series of questions on object inheritance. In addition to answering the questions, I created the following application to demonstrate inheritance among different objects.

The first piece of code are different shape classes. Some inherit from an IShape interface.

The second piece of code is a console application that uses these classes in different inheritance scenarios. The console.write tells the use case.

I would like feedback if my implementation looks correct.

Class definitions

using System;
using OOP.Interfaces;

namespace OOP.Models
{
    public class Circle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("Circle object's draw method\n");
        }
    }

    public class Rectangle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("Rectangle object draw method\n");
        }
    }

    public class Square : Rectangle
    {
        public void Draw()
        {
            Console.WriteLine("Square object draw method\n");
        }
    }

}


Console App

using System;
using OOP.Interfaces;
using OOP.Models;

namespace OOP_Calling_Client
{
  public class Program
  {
    static void Main(string[] args)
    {
        Console.WriteLine("This is a demo console app that shows examples of OOP inheritance through a series of shape classes and interfaces.");
        Console.WriteLine("*********************************\n");

        DrawCircle();
        DrawRectangle();
        DrawSquare();
        AssignDifferentTypesToSameInstanceVariable();
        Console.Read();
    }

    private static void DrawCircle()
    {
        IShape circle = new Circle();
        circle.Draw();
        Console.WriteLine("Object of type circle stored in a variable of type IShape\n");
        Console.WriteLine("*********************************\n");
    }

    private static void DrawRectangle()
    {
        Console.WriteLine("Object of type rectangle stored in a variable of type rectangle\n");
        Rectangle rectangle = new Rectangle();
        rectangle.Draw();
        Console.WriteLine("*********************************\n");
    }

    private static void DrawSquare()
    {
        Console.WriteLine("Object of type square stored in a variable of type rectangle. Rectangle is derived from square\n");
        Rectangle rectangle = new Square();
        rectangle.Draw();
        Console.WriteLine("*********************************\n");
    }

    private static void AssignDifferentTypesToSameInstanceVariable()
    {
        Console.WriteLine("Instance variable holds a type of circle, and then a type of rectangle. The draw methods change\n");
        IShape shape = new Circle();
        Console.WriteLine("The object variable is of type IShape,\nand is holding an instance of a Circle.\n");
        shape.Draw();
        Console.WriteLine("The object variable is of type IShape,\nbut is now holding an instance of a Rectangle.\n");
        shape = new Rectangle();
        shape.Draw();
    }
  }
}
Shadowing

There is some shadowing going on between Rectangle and Square. 

Rectangle implements IShape, and Square inherits from Rectangle.

As it stands, Square is hiding Rectangles Draw method. This is evident from the following compiler warning:


  Warning   1   'ConsoleApplication1.Square.Draw()' hides inherited member
  'ConsoleApplication1.Rectangle.Draw()'. Use the new keyword if hiding
  was
  intended.


This can pose a problem in the following scenario:

  Square s = new Square();
  s.Draw(); //Square method called

  Rectangle r = new Square();
  r.Draw(); //Rectangle method called!


As you see, this breaks inheritance and will only call the method on Square if the variable is a Square.

Instead, you might want to make the method virtual on Rectangle:

public class Rectangle : IShape
{
    public virtual void Draw()
    {
        Console.WriteLine("Rectangle object draw method\n");
    }
}

public class Square : Rectangle
{
    public override void Draw()
    {
        Console.WriteLine("Square object draw method\n");
    }
}


This will ensure that the correct method is always called.

Line breaks

There is no need to add \n when calling Console.WriteLine. It will add a line break automatically.

Moreover, \n is not the correct method of adding a line break in .NET. Use Environment.NewLine instead.

Misc.

The order of the final print in your example is wrong. It prints before actually assigning shape = new Rectangle().