Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why virtual is allowed while implementing the interface methods?

I have one specific query with the interfaces.

By default interface methods are abstract and virtual so if we implement that interface and gives definition in the class we actually override that method but when we mark the method as a virtual again in the implementing class why the compiler is not considering that we are actually trying to hide the original interface virtual method.

Like if we have a virtual method in the base class and derived class again marked the method as virtual in that case compiler gives the warning that you are hiding the base class method so use new if you are intentionally hiding the base class method.

public interface ITestInterface
{
    void virtualmethod(); // this method is by default virtual. 
}
public class TestInterface :ITestInterface
{
   public virtual void virtualmethod()
   {
    // Now compiler should consider that i am actually hiding the interface virtual method.
   }
}

if you build the above code for interface and open in ILDASM you will see the code like this:

.method public hidebysig newslot abstract virtual
         instance void virtualmethod() cil managed
{
}//end of method ITestInterface::virtualmethod
like image 829
Mohit Bhandari Avatar asked Dec 17 '10 12:12

Mohit Bhandari


2 Answers

Methods that are implemented from an interface are not virtual by default. You are merely providing an implementation of the contract defined in the interface definition. By marking the method as virtual, you are allowing derived classes to provide additional or separate implementation while still honoring the contract as defined.

Consider this example:

interface IAnimal
{
    string Speak();
}

class Dog : IAnimal
{
    public string Speak()
    {
        return "Bark!";
    }
}

The Dog class is implementing the interface by providing an implementation of the contract IAnimal. There are no virtual methods here and no overriding.

Now consider this example:

interface IAnimal
{
    string Speak();
}

class Dog : IAnimal
{
    public virtual string Speak()
    {
        return "Bark!";
    }
}

class GoldenRetriever : Dog
{
    public override string Speak()
    {
        return "I am a golden retriever who says " 
                   + base.Speak();
    }
}

Now the Dog class has declared Speak to be virtual which allows derived classes to provide an additional or new implementation. This does not break the contract with IAnimal as any call to the Speak method still returns a string.

Ok, one last example. Remember that interfaces don't require an implementation - they only require that the contract is satisfied. This means that the interface only cares that a member exists in the implementing class that has a matching signature. This means that we could also do this:

interface IAnimal
{
    string Speak();
}

abstract class Dog : IAnimal
{
    public abstract string Speak();
}

class GoldenRetriever : Dog
{
    public override string Speak()
    {
        return "I am a golden retriever";
    }
}

Notice now that the Dog class provides no implementation at all for Speak yet has satisfied the requirements of the contract.

Interfaces are also inherited from class to class so in all the examples above both Dog and GoldenRetriever implement the IAnimal interface. Neither class hide the Speak method - both classes implement it.


Ok, I think your confusion may be coming from the fact that the virtual method is defined in an interface, not a class. Here is the IL for the interface I defined above:

.class private interface abstract auto ansi IAnimal
{
    .method public hidebysig newslot abstract 
        virtual instance string Speak() cil managed
    {
    }
}

While you are correct that the method is defined as virtual you also need to notice that the type here is designated as an interface. This is purely an implementation detail of the MSIL generated by Microsoft's C# compiler - another compiler could easily generate different code as long as semantically it provided the same result.

The important thing here is this: even though the method is declared as virtual in the interface that does not mean that it is the same thing as a virtual method declared in class.

like image 122
Andrew Hare Avatar answered Sep 24 '22 07:09

Andrew Hare


Interface is not Base Class, so implementation methods are not overriden. Interface only declares the methods, Interface methods are not virtual by default, infact interfaces only declare the methods that are available on the class that implements that interface.

Declaration can not be virtual.

Implementation can or cannot be virtual that is completely dependent on the implementer's logic.

like image 25
Akash Kava Avatar answered Sep 25 '22 07:09

Akash Kava