C# Interfaces

In C#, if a number of classes need to be defined that should contain similar properties and methods, an interface can be used to enforce these similarities. An interface defines what a class should implement, in terms of properties and methods, without including how these should be implemented, and takes the following form.

interface Interface_name
{
    // Properties and methods with no body.
}

By convention, the name of an interface usually starts with a capital 'I', to make it easily recognisable as an Interface. Below is an example of an interface called 'IAnimal', that has two properties, 'Name' and 'Breed', as well as a method called 'Describe'.

// IAnimal interface.
interface IAnimal
{

    // Properties.
    string Name { get; set; }
    string Breed { get; set; }

    // Method.
    string Describe();

}

In order for a class to implement an interface, its name must be followed by a colon and then the name of the interface. Below are example classes, 'Dog' and 'Cat', that both implement the 'IAnimal' interface.

// Dog class that implements the IAnimal interface.
public class Dog : IAnimal
{
        
    // Constructor.
    public Dog(string name, string breed)
    {
        // Set the name and breed of the dog.
        this.Name = name;
        this.Breed = breed;
    }

    // Implement the required properties from the interface.
    public string Name { get; set; }
    public string Breed { get; set; }

    // Implement the required method from the interface.
    public string Describe()
    {
        // Return a string including the breed and name properties.
        return $"I am a type of dog called a {this.Breed} and my name is {this.Name}.";
    }

}

// Cat class that implements the IAnimal interface.
public class Cat : IAnimal
{

    // Constructor.
    public Cat(string name, string breed)
    {
        // Set the name and breed of the cat.
        this.Name = name;
        this.Breed = breed;
    }

    // Implement the required properties from the interface.
    public string Name { get; set; }
    public string Breed { get; set; }

    // Implement the required method from the interface.
    public string Describe()
    {
        // Return a string including the breed and name properties.
        return $"I am a {this.Breed} cat and my name is {this.Name}.";
    }

}

Both the 'Dog' and 'Cat' class have constructors, which accept two string parameters, 'name' and 'breed'. These values are added to the corresponding properties of the class. Again, both classes have a 'Describe' method, which returns a string description, containing the 'Name' and 'Breed' properties. It should be noted that if a class doesn't fully implement an interface, then a compilation error will result.

Below is an example of the 'Dog' and 'Cat' classes being instantiated, along with the 'Describe' methods being called for each.

class Program
{

    static void Main(string[] args)
    {

        // Create an instance of the dog class.
        Dog dog = new Dog("Rustie", "Jack Russell");

        // Display the result of calling the Describe method of the dog.
        Console.WriteLine(dog.Describe());

        // Create an instance of the cat class.
        Cat cat = new Cat("Tabitha", "Persian");

        // Display the result of calling the Describe method of the cat.
        Console.WriteLine(cat.Describe());

    }

}

The result of running this is as follows.

I am a type of dog called a Jack Russell and my name is Rustie.
I am a Persian cat and my name is Tabitha.