Bartek
Bartek

Reputation: 51

Why can't I implement a default interface method in a class inheriting an abstract class that inherits that interface?

I have an interface and an abstract class inheriting this interface.

public interface ISomeInterface
{
    int Method()
    {
        return 1;
    }
}

public abstract class SomeAbstractClass : ISomeInterface {}

Now I want to implement a class inhereting SomeAbstractClass that will also implement int Method().

public class SomeClass : SomeAbstractClass
{
    public int Method()
    {
        return 2;
    }
}

However when calling Method() on a casted SomeClass object to ISomeInterface it'll display 1.

ISomeInterface someClass = new SomeClass();
Console.WriteLine($"{someClass.Method()}"); // displays 1

But if I add interface to SomeClass

public class SomeClass : SomeAbstractClass, ISomeInterface
{
    public int Method()
    {
        return 2;
    }
}

It'll display 2.

Why is that the case? Is there any way to declare/implement Method() by just inhereting from SomeAbstractClass but without the need to write , ISomeInterface too?

I also don't want to modify the SomeAbstractClass if possible.

I tried searching for the explanation online, but it's difficult to explain this problem in a simple sentence. I've tried to read more about default interface methods, but learned nothing meaningful.

Upvotes: 5

Views: 96

Answers (1)

Sweeper
Sweeper

Reputation: 273275

As you have noticed, the Method declared in SomeClass does not implement ISomeInterface.Method. You cannot implement ISomeInterface.Method in SomeClass, because SomeAbstractClass has already fully implemented ISomeInterface.

By not declaring any members matching the signature of ISomeInterface.Method, SomeAbstractClass fully implements ISomeInterface by "opting in" for the default implementation of Method.

This is consistent with how abstract classes usually work - if Method didn't have a default implementation, an empty SomeAbstractClass would have caused a compiler error. If you want SomeAbstractClass to not implement Method, and let its concrete subclasses do the job instead, you need to add the following to SomeAbstractClass (regardless of whether Method has a default implementation):

public abstract int Method();

When Method does have a default implementation, this is called reabstraction.

See also this question, which is about how you still have to declare the member in the abstract class, in order for it to implement a non-default interface member.

Note that by adding the abstract method to SomeAbstractClass, you would now also be able to call Method on things of type SomeAbstractClass, whereas you couldn't previously.


The situation is kind of like this:

// not actually how default interface members are implemented under the hood,
// just for illustration purposes only
public interface ISomeInterface
{
    int Method();
}

public abstract class SomeAbstractClass : ISomeInterface {

    public int Method() => 1;
}

public class SomeClass : SomeAbstractClass
{
    public int Method() => 2; // this method obviously does not implement ISomeInterface.Method!
}

Upvotes: 2

Related Questions