Home > Software engineering >  Question about assigning a instance of a class to an interface type
Question about assigning a instance of a class to an interface type

Time:09-23

I Don't understand some things about the below code, I wonder if you can help me.

What first confused me is the following explanation from Microsoft docs;

enter image description here

What I didn't understand is why I am assigning "myClass" to variable "myInterface" of type "IMyInterface".

Firstly, I'm surprised this is allowed, You can't assign a String to an Int variable, so why can i assign an instance of a class type to a variable of an Interface type?

Microsoft Docs mentions "an interface cannot be instantiated using the new operator", But why would you want to instantiate an interface. Isn't the design of interfaces that they are just a contract enforcing any inheriting class to implement the properties and methods that the interface contains, why would you ever need to assign a class to an interface?

I Investigated exactly the rules surrounding the Microsoft docs piece below, I realized that if you declare an interface, inherit it in another class, you can then assign the class that has inherited that interface to a variable of the interface type, then call the variable of the interface type as if it was a class ( the whydoesthiswork variable in the below code).

This hasn't helped me understand why this is possible, what the point in this confusing syntax is and why you would ever want to do this.

Any help would be appreciated, thank you.

interface IAnimal
{
    void animalSound(); 
}

class Pig : IAnimal
{
    public void animalSound()
    {
        Console.WriteLine("The pig says: wee wee");   
    }
}

class Program
{
    static void Main(string[] args)
    {            
        IAnimal whydoesthiswork = new Pig();  
        whydoesthiswork.animalSound();
    }
}

CodePudding user response:

You've discovered polymorphism - a core feature of object-oriented languages that allows you to treat objects as their parent class/interface.

You can't assign a String to an Int variable, so why can i assign an instance of a class type to a variable of an Interface type?

A string and an int do not derive from each other - obviously assigning a string to an int doesn't make sense. A pig is an animal, however, so it makes sense to treat it as such.

why you would ever want to do this?

It allows you to write code that works for any animal, such that if you introduce a new animal in the future, your code will stay the same. Consider this function:

void Pet(Pig pig)
{
    Console.WriteLine("Petting...");
    pig.animalSound();
}

If tomorrow you decide to add a Dog class which can also be pet, you'd have to write an exact copy of this function, just replaced with Dog! That's bad software design. Instead, we can write 1 generic function that works for both pigs and dogs!

void Pet(IAnimal animal)
{
    Console.WriteLine("Petting animal...");
    animal.animalSound();
}

CodePudding user response:

You don't have to do that in this limited example.

If you have a lot of animal types though, you could pass them to functions that accept IAnimal rather than the concrete type. You could create a List<IAnimal> or IAnimal[] with different animals, iterate over them and call animal.animalSound() without knowing the concrete type.

For example:

interface IAnimal
{
    void makeSound(); 
    void Wake();
    void Sleep();
}

class Cat : IAnimal
{
...
}

class Dog : IAnimal
{
...
}

Assuming you have this method :

void MoveAround(IAnimal animal)
{
    animal.Wake();
    animal.MakeSound();
    animal.Sleep();
}

You can apply it to an array of animals

var animals=new[]{new Pig(), new Cat(), new Dog()};

foreach(var animal in animals)
{
    MoveAround(animal);
}

CodePudding user response:

An interface is used to define a contract. It contains a set of members that types that implement the interface must implement. So you can be sure that every type that implements the interface does at least support the members of the interface.

You can use an interface to declare a variable. Any instance that is assigned to it, must implement the interface. If you use the variable, you can only use the members of the interface, not the ones of the actual instance.

In your example, if you add another method to pig, you could not use this method because you declared the variable as the interface type:

interface IAnimal
{
    void animalSound(); 
}

class Pig : IAnimal
{
    public void animalSound()
    {
        Console.WriteLine("The pig says: wee wee");   
    }

   public void RollInTheDirt() 
   {
   }
}

class Program
{
    static void Main(string[] args)
    {            
        IAnimal whydoesthiswork = new Pig();  
        whydoesthiswork.animalSound();
        whydoesthiswork.rollInTheDirt(); // Error, because the variable is of type IAnimal, not of type Pig
    }
}

Why do you need this?

You can use interfaces to define requirements towards type in a loosely coupled manner. If you have code that can run on all types of animals, because it only uses the AnimalSound method, you can use a parameter of type IAnimal instead of restricting the method to pigs by using Pig as the parameters type. If you later decide to implement another kind of animal, let's say a bird, you can also implement the AnimalSound method with the sound of the bird. You can continue to use your method also with the bird - even though the animals do not have very much in common, but agreed to at least be able to make a sound. This increases the flexibility of your code a lot.

  •  Tags:  
  • c#
  • Related