Reputation: 51
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
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