Why Are C# Interface Methods Not Declared Abstract or Virtual

Why are C# interface methods not declared abstract or virtual?

For the interface, the addition of the abstract, or even the public keywords would be redundant, so you omit them:

interface MyInterface {
void Method();
}

In the CIL, the method is marked virtual and abstract.

(Note that Java allows interface members to be declared public abstract).

For the implementing class, there are some options:

Non-overridable: In C# the class doesn't declare the method as virtual. That means that it cannot be overridden in a derived class (only hidden). In the CIL the method is still virtual (but sealed) because it must support polymorphism regarding the interface type.

class MyClass : MyInterface {
public void Method() {}
}

Overridable: Both in C# and in the CIL the method is virtual. It participates in polymorphic dispatch and it can be overridden.

class MyClass : MyInterface {
public virtual void Method() {}
}

Explicit: This is a way for a class to implement an interface but not provide the interface methods in the public interface of the class itself. In the CIL the method will be private (!) but it will still be callable from outside the class from a reference to the corresponding interface type. Explicit implementations are also non-overridable. This is possible because there's a CIL directive (.override) that will link the private method to the corresponding interface method that it's implementing.

[C#]

class MyClass : MyInterface {
void MyInterface.Method() {}
}

[CIL]

.method private hidebysig newslot virtual final instance void MyInterface.Method() cil managed
{
.override MyInterface::Method
}

In VB.NET, you can even alias the interface method name in the implementing class.

[VB.NET]

Public Class MyClass
Implements MyInterface
Public Sub AliasedMethod() Implements MyInterface.Method
End Sub
End Class

[CIL]

.method public newslot virtual final instance void AliasedMethod() cil managed
{
.override MyInterface::Method
}

Now, consider this weird case:

interface MyInterface {
void Method();
}
class Base {
public void Method();
}
class Derived : Base, MyInterface { }

If Base and Derived are declared in the same assembly, the compiler will make Base::Method virtual and sealed (in the CIL), even though Base doesn't implement the interface.

If Base and Derived are in different assemblies, when compiling the Derived assembly, the compiler won't change the other assembly, so it will introduce a member in Derived that will be an explicit implementation for MyInterface::Method that will just delegate the call to Base::Method.

So you see, every interface method implementation must support polymorphic behavior, and thus must be marked virtual on the CIL, even if the compiler must go through hoops to do it.

Comparison : interface methods vs virtual methods vs abstract methods

Virtual and abstract are almost the same. A virtual method has an implementation in the base class that can optionally be overridden, while an abstract method hasn't and must be overridden in a child class. Otherwise they are the same. Choosing between them depends on the situation. If you got a base implementation, you use virtual. If you don't, and you need every descendant to implement it for itself, you choose abstract.

Interface methods are implementations of a method that is declared in an interface that the class implements. This is quite unrelated to the other two. I think a method can be both virtual and interface. The advantage of interfaces is that you declare one interface (duh) that can be implemented by two totally different classes. That way, you can run the same code on two different classes, as long as the methods you'd like to call are declared in an interface they share.

Is an interface and an abstract class with just virtual abstract methods the same thing?

There are 2 main differences between Interfaces and abstract super-classes:

Abstract Classes

  • code reuse is possible by using an abstract super-class
  • you can only inherit one super-class

Interfaces

  • every method has to be implemented in each sub-class
  • a class can inherit more than 1 interface (multiple inheritance)

Reflection says that interface method are virtual in the implemented type, when they aren't?

All methods declared in an interface are marked as virtual abstract, and all methods that implement interface methods in classes are marked as virtual final, so the CLR knows it can't just call them directly - it has to do vtable lookups at runtime to call the right implementation. The interface implementations are still virtual, but you can't override them as they're final.

As an example, the following C# definition:

public interface IInterface {
void Method();
}

public class Class : IInterface {
public void Method() {}
}

compiles to the following IL:

.class public interface abstract IInterface {
.method public abstract virtual instance void Method() {}
}

.class public Class extends [mscorlib]System.Object implements IInterface {
.method public specialname rtspecialname instance void .ctor() {}
.method public virtual final instance void Method() {}
}

If a virtual method is declared abstract

It becomes clearer when you look at the code example directly above the quoted paragraph:

public class D
{
public virtual void DoWork(int i)
{
// Original implementation.
}
}

public abstract class E : D
{
public abstract override void DoWork(int i);
}

The virtual method D.DoWork is inherited by E, and, there, declared abstract. The method is still virtual, it has just become abstract as well.

As you correctly state, an abstract method is always virtual. If your friend is still unconvinced, here's an official quote for that:

An abstract method is implicitly a virtual method.

Why do abstract classes need to define abstract methods from interfaces they implement?

An abstract class is a fully-fledged type, just except it cannot be instantiated. Hence its full contract must be declared even though some of its methods are not implemented. A user of a particular abstract class must be able to bind to all its methods, be they coming from interfaces or directly declared in the abstract class. It the methods from interfaces were not (at least) declared (if not even implemented) in the abstract class, the used couldn't bind to them.

Further, classes and interfaces are somewhat loosely-coupled. A class may declare a method, which is later mapped to a same-signature method in an interface which is implemented by its descendant. Hence it is again a “good idea” from the language-design viewpoint to require all methods of interfaces being directly implemented on an abstract class to be actually declared in it.

You can think of an interface as a detachable feature (except when explicit implementations are used). The abstract class may live on its own and its direct users need not to know of any of its interfaces.

It's a design feature that only virtual methods can be left without an implementation, because the technical mechanism of virtual methods needs to be leveraged for the whole concept of abstract classes work in practice.


UPDATE: Example:

public interface IFoo { void M(); }

public abstract class Bar : IFoo
{
public virtual abstract void M();

public void N() { }
}

public class Baz : Bar
{
public override void M() { … }
}



public void Method(Bar par)
{
par.M();
}



Baz x = new Baz();
Method(x);

The Method see the instance denoted by the variable x as Bar — neither as Baz nor as IFoo. In other words, the user of class Bar does not care of whether it implemented one, two, ten, or no interface at all. All it does is access its members. It rely's on Bar's contract, not of IFoos contract. Hence if Bar implements IFoo, it must define all members from IFoo.

Explicit interface implementation cannot be virtual

however this way I've really no indication at all that I'm overriding something

Well, you do, sort of - you have the fact that it's clearly an explicit interface implementation. That shows it's providing polymorphic behaviour for that method call which is specified on an interface... why does it matter whether the base class also implemented the interface? What difference will it make to you when you read the code?

To me, the main benefit of stating override is to make sure I've really got the right signature - that it matches the thing I'm trying to override. You've already got that benefit with explicit interface implementation, as if you give a non-existent method or the wrong parameters etc, the compiler will already complain.

I can sort of see your point, but I've never found it to be an actual problem.

Questions about Abstract method and interface method

  1. Interface methods are abstract methods. Yes they are the same as abstract methods in abstract classes as both are abstract. A caveat here though is how they are handled when polymorphism comes into play. This can be illustrated with the following code:

    interface IA 
    {
    int xxx();
    }

    abstract class B
    {
    public abstract int yyy();
    }

    class C : B, IA
    {
    public int xxx()
    {
    return 1;
    }

    public int yyy()
    {
    return 1;
    }
    }

The yyy definition actually hides the abstract method in B and needs to be declared as public override int yyy()... to prevent this.


  1. No. you cannot "partially implement the non-abstract methods in abstract class". You can partially implement an abstract class by providing some concrete methods and some abstract methods. You cannot "partially implement" an abstract method though. A method in an abstract class is either abstract or it isn't.

  2. In your code example, OrdinaryClass is providing an implementation of xxx. OrdinaryClass2 is hiding that abstract method though and providing its own xxx. as mentioned in (1). Please read up on method hiding in C# for more details, eg http://www.akadia.com/services/dotnet_polymorphism.html and Overriding vs method hiding.



Related Topics



Leave a reply



Submit