0

Studying C# and have a random question I cannot seem to figure out. I've seen code that declares a variable of an interface type. So for instance: ISomeInterface someInterface = ... instead of ClassImplementingInterface someObject = ...

1) Why would you ever want to declare a variable to be of an interface type instead of the actual object that implements it?

2) Are there advantages or disadvantages... does this practice have a name attached to it so I can read up on it some more?

  • To answer your second question, the practice of doing this is called Polymorphism. – Anzurio May 11 '20 at 22:09
  • To answer the first, so that you can decouple dependencies. If you take an interface then users can pass anything that implements it and you only care about the API that the interface exposes. – juharr May 11 '20 at 22:11
  • 1
    See also: https://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface – greenjaed May 11 '20 at 22:13
  • Both `Banana` and `Orange` might implement the `IHasPeel` interface, but their base class `Fruit` does not (you don't peel a strawberry). A class describes what something *is*, an interface describes what something *has*. – Rufus L May 11 '20 at 23:55
  • Also, a class may only implement one other class as it's base, but it may implement many different interfaces. – Rufus L May 11 '20 at 23:56

1 Answers1

1

One practical example of when we might do this is when we want to have the object behave within the constraints of the specific interface after creation. Consider the following code:

public static void Main()
{
    IReadableFruit fruit = new Apple("big");
    fruit.FruitSize = "small"; // this does not work!
    fruit.EatFruit(); // nor does this!

    Apple apple = new Apple("big");
    apple.FruitSize = "small"; // this does!
    apple.EatFruit(); //and so does this.
}

public interface IReadableFruit 
{
    string FruitSize { get; }
}

public interface IEdibleFruit 
{
    void EatFruit();
}

public class Apple : IReadableFruit, IEdibleFruit
{
    public string FruitSize { get; set; }

    public Apple(string fruitSize)
    {
        FruitSize = fruitSize;
    }

    public void EatFruit()
    {
        Console.WriteLine("om nom nom");
    }
}

In the first instantiation, we use the interface, which defines the attribute as readable but not necessarily writable; once we've instantiated the fruit, it now behaves only within the bounds that the IReadableFruit interface described, even if the actual class inherited from other interfaces or had other attributes or methods available in the implementation.

As @Anzurio mentioned in his comment, this is one example of polymorphism.

Adam
  • 3,339
  • 1
  • 10
  • 15