4

I would like to know the difference between these two Instantiation

interface ITest
{
    int TotalMarks(int englishMarks, int mathematicsMarks);
}

class TestClass : ITest
{
    public int TotalMarks(int engMarks, int mathMarks)
    {
        return engMarks + mathMarks;
    }
}

class Program
{
    static void Main(string[] args)
    {
        TestClass c = new TestClass();
        Console.Write(c.TotalMarks(10, 20));
        Console.Write("\n");

        ITest c1 = new TestClass();
        Console.Write(c1.TotalMarks(21, 34));

        Console.ReadKey();
    }
}
  • TestClass c = new TestClass();
  • ITest c1 = new TestClass();

    they both work and give result as expected. How these two differ and when to use which ?

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
NoobieDude
  • 93
  • 6

2 Answers2

7

The difference is that on second one using an interface you can only access those members which are present on that specific interface instead the whole class. This allows you to implement a few different interfaces on your actual class, whereas only a specific "contrainer" is accessable by the user.

Furthermore interface-driven design is good on unit-testing as you can simply exchange one class by another.

Imagine you have another class that also implements your interface. If a method you created in any context would expect you actual class as parameter you would now have to change that method´s signature in order to also allow instances of your second class. If the method is designed for interfaces instead you can pass both - TestClass and AnotherTestClass-instances to it without taking care what type it actual is. This reduces class-coupling as you´re no longer depending on an actual class but only the members an interface defines. How those members are implemented does not have any meaning to your consuming code.

Also take care when casting. Whilst you can say that every instance of TestClass also implements ITest not all instances of ITest are of type TestClass. Thus the following produces an InvalidCastException at runtime:

ITest t = new TesClass();
AnotherTestClass t2 = (AnotherTestClass) t;

All in all an interface only says what an instance of that interface can do, but not how it achieves this as this should be unimportant for any consuming code. To stay on your example: your Program won´t need to know how TotalMarks is actually implemented as long as it knows that the method actually exists and returns what it is supposed to return. The implementation-details are of no meaning the Program. This is what is called losly class-coupling.

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • 1
    Just to add up, interface also allows to make your code more flexible, a class will rely on an interface and not on another class (though interface is class). So if you have a module expecting a IMoving object, it can receive either Cat or Dog and work. Next year, you do a program for car and your module also works for car as long as your Car class implements IMoving. – Everts Feb 24 '16 at 07:05
  • @fafase see the third paragraph of my answer if this is what you mean. – MakePeaceGreatAgain Feb 24 '16 at 07:07
  • Thank you explaining it so neatly I am starting to get the idea of a loosely coupled class with the help of an interface. I have another doubt regarding interface. ITest t = new ITest(); throws an compiler error. Yes It make sense since Interface doesn't have definition of the methods it can't do anything on its own. So we can't instantiate it. But when we say ITest t = new TestClass() how come it is able to instantiate (create an instance of an interface) it? The interface still doesn't have any definition of the methods in it? I hope you got my question.. – NoobieDude Feb 24 '16 at 07:25
  • @HimBromBeere Mmm that might be yes. Let's say my context of cat, dog and car might be more pedagogic :). – Everts Feb 24 '16 at 07:36
  • @fafase I wanted to stay on the structure OP already uses. However you might be right that using `Car` and `cat` might be pedagogic :) – MakePeaceGreatAgain Feb 24 '16 at 07:38
  • 1
    It instantiates because you use new TestClass(). this is a fully implemented object type. Then the address of that object is passed to a variable of type ITest and that guy can only access what ITest knows. t points to a TestClass object but t only sees ITest part of it. If you cast to a TestClass, TestClass tc = (TestClass)t; it will work and tc is now seeing the whole TestClass object. You are not instantiating a ITest object, you cannot instantiate interfaces as they are not fully implemented. – Everts Feb 24 '16 at 07:38
3

There could be many difference but few of major I would mention

ITest c1 = new TestClass();

Using this Interface to create object allows to create object of any class that implements the ITest like TestClass

class AnotherTestClass : ITest
{
    public int TotalMarks(int engMarks, int mathMarks)
    {
        return engMarks + mathMarks;
    }
}

 ITest c1 = new AnotherTestClass();

On the other hand declare some new method in TestClass and try to access it with c1 created through interface you wont be able to access it but you can access the new method if you create through class in the first method through the class instead of interface as shown below.

class TestClass : ITest
{
    public int TotalMarks(int engMarks, int mathMarks)
    {
        return engMarks + mathMarks;
    }
    public void AdditionalMethod()
    {

    }
}

TestClass c = new TestClass();
c.AdditionalMethod(); //Valid
ITest c1 = new TestClass();
c1.AdditionalMethod(); //Invalid, compilation error

Interfaces help us in creating loosely coupled applications by acting upon pattern program to interface not an implementation, you can read more about it here and here.

Community
  • 1
  • 1
Adil
  • 146,340
  • 25
  • 209
  • 204