Brahim Boulkriat
Brahim Boulkriat

Reputation: 992

Code work despite the interface is not implemented

I have the following code :

 interface ICalculator
 {
     int Sum ( int x,  int y);
 }

 abstract class AbsCalculator
 {
     public abstract int Sum(int x, int y);
 }

 class Calculator : AbsCalculator, ICalculator
 {
     public override int Sum(int x, int y)
     {
         Console.WriteLine ( "From overriden method" );
         return x + y;
     }
 }

The following statements works fine and the program compile despite i didn't implement the interface :

Calculator calculator = new Calculator();
Console.WriteLine ( calculator.Sum(10, 20) );

So my first question is : Why did it work ?

Then, i add the following interface implementation to Calculator class :

int ICalculator.Sum(int x, int y)
{
     Console.WriteLine("From implemented method");
     return x + y;
}

When trying again the following statement :

Calculator calculator = new Calculator();
Console.WriteLine ( calculator.Sum(10, 20) );

The method overriden from the abstract still called. So my second question is : Why did the program call the method from the abstract class and not the method from the interface?

Upvotes: 8

Views: 720

Answers (3)

Gun
Gun

Reputation: 1411

Answer for your first Qusetion

In .NET When ever a type(Class) is loaded the CLR creates a method table and this table contains entries for the methods defined by the class and the methods inherited by the class so in your case The Calculator class contains the following entries

  1. By default every class implicitly inherited from Object base class so the method table contains the entries for each virtual instance methods defined by the Object class.

  2. Your class is inheriting from AbsCalculator abstract class so the method table defines an entry for the abstract class method Sum

  3. Your class is inheriting the ICalculator interface so the method table defines an entry for the interface Sum method.

Here the C# compiler make an assumption that you are implementing the interface method because the method is Public and the signature of the interface method and abstract class method is same. so the compiler didn't give any error

Answer for your Second Question

While Implementing there are two concepts Implicit Interface Method Implementation and Explicit Interface Method Implementation

In Implicit Interface Method Implementation we are calling the interface methods with interface reference like as shown in below

    Calculator calculator = new Calculator();
    ICalculator icalc = calculator;

    calculator.Sum(5,5);
    icalc.Sum(5,10);

In Explicit Interface Method Implementation when you prefix the name of the method with the name of the interface then it becomes explicit method implementation.

interface ICalc
{
    int Sum(int x, int y);
}

abstract class AbsCalc
{
    public abstract int Sum(int x, int y);
}

class Program : AbsCalc, ICalc
{
    public override int Sum(int x, int y)
    {
        Console.WriteLine("From abstract Override");
        return x + y;
    }

    int ICalc.Sum(int x,int y)
    {
        Console.WriteLine("From Intrface");
        return x + y;
    }


    static void Main(string[] args)
    {
        Program p = new Program();
        p.Sum(1, 2);

        ICalc i = p;
        i.Sum(1,2);
    }
}

Upvotes: 4

Bogdan Beda
Bogdan Beda

Reputation: 788

There are two ways to implement interfaces in C#, either explicit or implicit but CLR has only one type of implementation - the explicit one.

When C# compiler sees that a class must implement an interface, it looks for methods matching the signatures of required classes by that interface and instructs CLR that those are implementations, to save you code.

So, in your case, When C# compiler sees that your class implements ICalculator, it will look for a public method which matches signature of Sum(int, int) and will consider that method the implementation. The fact that that method is overriden is not important.

If you want to give another meaning to the implementation of the method, you should give it explicitly.

Upvotes: 5

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137398

No, you are impelementing it! Your first block of code is perfectly legal. The name and signature matches what the interface requires: int Sum(int x, int y).

Now, a signature like int ICalculator.Sum(int x, int y) is called explicit interface implementation, which means you can only access that method via a reference of the interface type.

interface ICalculator {
    int Sum ( int x,  int y);
}

abstract class AbsCalculator {
    public abstract int Sum(int x, int y);
}

class Calculator : AbsCalculator, ICalculator {
    public override int Sum(int x, int y) {
        Console.WriteLine ( "From overriden method" );
        return x + y;
    }

    int ICalculator.Sum(int x, int y) {
         Console.WriteLine("From explicitly implemented interface method");
         return x + y;
    }
}

class Program {
    static void Main() {
        Calculator calculator = new Calculator();
        ICalculator icalc = calculator;

        // These calls will print different messages.
        calculator.Sum(10,20);
        icalc.Sum(10,20);
    }
}

Upvotes: 4

Related Questions