o7planning

Abstract class and Interface in C#

  1. Introduction
  2. Abstract Class
  3. Abstract class, the examples
  4. Overview of the interface
  5. Structure of an Interface
  6. Class implements Interface

1. Introduction

In this document, I will instruct you in Interface and Abstract Class, also analyze the similarities and differences between them.
Firstly you need to create a project called AbstractClassInterface to practice examples.
Setting it is the default project.

2. Abstract Class

Abstract class. For example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{
   // A class has at least one abstract method,
   // must be declared as abstract.
   public abstract class ClassA
   {

       // This is an abstract method.
       // It has no body.
       // The 'access modifier' of this method is public
       public abstract void DoSomething();

       // The 'access modifier' of this method is protected.       
       protected abstract String DoNothing();

      
       protected abstract void Todo();
   }

   // This is an abstract class.
   // It is declared as abstract, although it does not have any abstract methods.   
   public abstract class ClassB
   {

   }
}
Characteristics of an abstract class is:
  • It was declared as abstract.
  • It can declare 0, 1 or more abstract methods inside.
  • You can not initialize one object directly from an abstract class.

3. Abstract class, the examples

See illustration:
AbstractJob.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{
    // Class has at least one abstract method, must be declared as abstract.
    public abstract class AbstractJob
    {

        public AbstractJob()
        {

        }

        // This is an abstract method,
        // It has no body.
        // This method returns the name of the job.
        public abstract String GetJobName();

        // This is an abstract method,
        // It has no body.
        public abstract void DoJob();

        // None abstract method.
        public void StopJob()
        {
            Console.WriteLine("Stop");
        }
    }
}
JavaCoding.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{
    public class JavaCoding : AbstractJob
    {

        public JavaCoding()
        {
        }

        // Implements the abstract method declared at the superclass.
        // It must have a body.
        // (The keyword 'override' is required.)
        public override void DoJob()
        {
            Console.WriteLine("Coding Java...");
        }

        // Implements abstract method of superclass.
        public override String GetJobName()
        {
            return "Java Coding";
        }

        public void TestExample()
        {
            Console.WriteLine("Testing Example...");
        }
    }

}
CSharpCoding.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{
    class CSharpCoding : AbstractJob
    {
        public CSharpCoding()
        {
        }

        // Implements the abstract method declared at the superclass.
        // (The keyword 'override' is required.)
        public override void DoJob()
        {
            Console.WriteLine("Coding CSharp...");
        }

        // Implements abstract method of superclass.
        public override String GetJobName()
        {
            return "CSharp Coding";
        }

        public void RunningExample()
        {
            Console.WriteLine("Running Example...");
        }
    }
}
ManualJob.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{

    // The parent class (AbstractJob) has two abstract methods.
    // This class is just implementing one abstract method of the parent class.
    // Therefore it is mandatory to declare as 'abstract'.
    public abstract class ManualJob : AbstractJob
    {

        public ManualJob()
        {

        }

        // Implement abstract method declared in the parent class.
        // This method will have body.
        // (Requires 'override' keyword).
        public override String GetJobName()
        {
            return "Manual Job";
        }

    }
}
BuildHouse.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{

    // This class extends from ManualJob class.
    // BuildHouse undeclared abstract.
    // So it needs to implement all remaining abstract methods.
    public class BuildHouse : ManualJob
    {

        public BuildHouse()
        {

        }

        // This method implement abstract method declared in the parent class.
        // This method will have body.
        // (Requires 'override' keyword).
        public override void DoJob()
        {
            Console.WriteLine("Build a House");
        }

    }

}
Demo
JobDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{
    public class JobDemo
    {

        public static void Main(string[] args)
        {
            // Create AbstractJob object via constructor of JavaCoding.
            AbstractJob job1 = new JavaCoding();

            // Call DoJob() method.
            job1.DoJob();

            // GetJobName() is abstract method in AbstractJob class.
            // But it has been implemented in a certain subclass
            // So can call it.
            String jobName = job1.GetJobName();

            Console.WriteLine("Job Name 1= " + jobName);


            // Create AbstractJob object via constructor of CSharpCoding.
            AbstractJob job2 = new CSharpCoding();

            // Call DoJob() method.
            job2.DoJob();

            String jobName2 = job2.GetJobName();

            Console.WriteLine("Job Name 2= " + jobName2);

            // Create AbstractJob object via constructor of BuildHouse.
            AbstractJob job3 = new BuildHouse();

            job3.DoJob();

            String jobName3 = job3.GetJobName();

            Console.WriteLine("Job Name 3= " + jobName2);


            Console.ReadLine();
        }
    }

}
Running example:
Coding Java...
Job Name 1= Java Coding
Coding CSharp...
Job Name 2= CSharp Coding
Build a Hourse
Job Name 3= CSharp Coding

4. Overview of the interface

We know that a class can only extend from only one other class.
// Class B is subclass of A, or B is extended from A
// CSharp only allow class extends from only one other class.
public class B : A  
{
  // ....
}

// In case you do not specify what this class extends from.
// CSharp understands that this class extends from the Object class.
public class B
{

}

// The way to declare this class is similar to above way.
public class B : Object
{

}
But a class can extend from several Interfaces
// A class extends from only one other class
// but can implememts many interfaces
public class Cat : Animal, CanEat, CanDrink
{

     // ....
}
The characteristics of interface in CSharp.
  • Interface has internal or public modifiers, if not specified, it is considered as internal by default.
  • Interface can not define the field.
  • Its methods are abstract and public method , and there is no function body. But when declaring, you are not allowed to specify public or abstract.
  • Interface have no Constructor.

5. Structure of an Interface

An interface in CSharp can declare modifiers is public or internal, if not declare, it will be automatcally considered asinternal. Interface with the public modifier can be used everywhere, to interface with internal modifier is only used within the Assembly.

An assembly is the compiled output of your code, typically a DLL, but your EXE is also an assembly. It's the smallest unit of deployment for any .NET project.

The assembly typically contains .NET code in MSIL (Microsoft Intermediate language) that will be compiled to native code ("JITted" - compiled by the Just-In-Time compiler) the first time it is executed on a given machine. That compiled code will also be stored in the assembly and reused on subsequent calls.

NoAccessModifierInterface.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{

    // This is an interface that does not declare 'access modifier'.
    // By default, Its 'access modifier' is 'internal'.
    // It can only be used within an Assembly.
     interface NoAccessModifierInterface
    {

    }

}
Methods of Interface are abstract and public, and there is no body. But when declaring, you are not allowed to specify public or abstract.
CanMove.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{

    // This interface defines a standard,
    // about things capable of moving.
    public interface CanMove
    {

        // The methods of the Interface are public and abstract.
        // (But you are not allowed to write the public or abstract here).
        void Run();

        // Back
        void Back();

        // Return Velocity.
        int GetVelocity();

    }

}
CanDrink.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{

    // This interface defines a standard,
    // about things capable of drinking.
    public interface CanDrink
    { 

          void Drink(); 

    }

}
CanEat.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{

    // This interface defines a standard,
    // about things capable of eating.
    public interface CanEat
    {

          void Eat(); 
    }

}

6. Class implements Interface

When a class implements an interface, you must implement or declare all methods that is included in interface.
  1. If you implements a certain method of interface, you have to write the content for the method, declare method is public.
  2. If you do not implements a certain method of interface, you must declare it in the class with the 'public abstract' keyword and not write the content of the method.
Let's see the example, Animal class implement CanMove interface.
Animal.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{

    // This class extends from Object.
    // And implements CanMove interface.
    // CanMove has 3 abstract methods.
    // This class implements only one abstract method of CanMove.
    // Therefore it must be declared as 'abstract'.
    // The remaining methods must be declared with 'public abstract'.
    public abstract class Animal : CanMove
    {

        // Implements Run() method of CanMove.
        // You have to write the contents of the method.
        // Access modifier must be public.
        public void Run()
        {
            Console.WriteLine("Animal run...");
        }

        // If this class does not implements a certain method of Interface
        // you have to rewrite it as an abstract method.
        // (Always is 'public abstract').
        public abstract void Back(); 

        public abstract int GetVelocity();

    }


}
Cat class inherits from the Animal class and implements 2 interfaces CanDrink and CanEat.
Cat.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{

    // Cat extends from Animal and implements 2 interface CanEat, CanDrink.
    public class Cat : Animal, CanEat, CanDrink
    {

        private String name;

        public Cat(String name)
        {
            this.name = name;
        }

        public String getName()
        {
            return this.name;
        }

        // Implements abstract method of Animal.
        // (Must specify the 'override').
        public override void Back()
        {
            Console.WriteLine(name + " cat back ...");
        }

        // Implements abstract method of Animal.
        // (Must specify the 'override').
        public override int GetVelocity()
        {
            return 110;
        }

        // Implements abstract method of CanEat.
        public void Eat()
        {
            Console.WriteLine(name + " cat eat ...");
        }

        // Implements abstract method of CanDrink.
        public void Drink()
        {
            Console.WriteLine(name + " cat drink ...");
        }

    }

}
Mouse.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{
    public class Mouse : Animal, CanEat, CanDrink
    {

        // Implements abstract method of Animal
        // (Must have keyword 'override').
        public override void Back()
        {
            Console.WriteLine("Mouse back ...");
        }

        // Implements abstract method of Animal 
        public override int GetVelocity()
        {
            return 85;
        }

        // Implements abstract method of CanDrink.
        public void Drink()
        {
            Console.WriteLine("Mouse drink ...");
        }

        // Implements abstract method of CanEat.
        public void Eat()
        {
            Console.WriteLine("Mouse eat ...");
        }

    }

}
AnimalDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractClassInterface
{

    public class AnimalDemo
    {

        public static void Main(string[] args)
        {

            // Create a CanEat object.
            // An object declared as CanEat
            // Actually it is the Cat.
            CanEat canEat1 = new Cat("Tom");

            // An object declared as CanEat
            // Actually it is the Mouse.
            CanEat canEat2 = new Mouse();

            // Polymorphism shown here.
            // CSharp know the actual type of an object.
            // ==> Tom cat eat ...
            canEat1.Eat();

            // ==> Mouse eat ...
            canEat2.Eat();

            bool isCat = canEat1 is Cat;// true

            Console.WriteLine("catEat1 is Cat? " + isCat);

            // Check 'canEat2' Is the mouse or not?.
            if (canEat2 is Mouse)
            {
                // Cast
                Mouse mouse = (Mouse)canEat2;

                // Call Drink() method (Inherited from CanDrink).
                mouse.Drink();
            }

            Console.ReadLine();
        }
    }

}
Running the example:
Tom cat eat ...
Mouse eat ...
catEat1 is Cat? True
Mouse drink ...