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.