Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change return type to derived type during override

I would like to have interace A. Which will allow objects of type A generate other objects of type A. I need the same behavior for type B. In my application is true that all B are also A. So I would like B to be derived from A.

This is my try:

public interface A {
    A method1();
}
public interface B : A {
    overrride B method1();
    void otherMethod();
}

Note that override keyword dosn't compile here. The only way to make the project compile is make the interface B look as follows:

public interface B : A {
    //A method1(); /* commented out because it is inherired */
    void otherMethod();
}

However I would like to promise by interface B, that objects of this type have method to produce other objects of type B.

Implementation of interface B could look like:

class Foo : B {
    B metod1();
}

Where I want B metod1() to be implemantation of B method1() from interface B and I also want the same method to be implementation of A method1() from interface A. I expect the same behavior in all classes implementing interface B. So I don't want to implement method1 each time twice for both interfaces.

I am doing this in c# with interfaces. But I believe that similar question could be interesting even with classes and possibly also in Java.

like image 578
John Bumper Avatar asked Oct 28 '25 09:10

John Bumper


1 Answers

The only way to do this properly is using generics like this:

public interface A<T> where T : A<T>
{
    T method1();
}

Then B looks like this:

public interface B : A<B>
{
    void otherMethod();
}

And finally, implementing a class would go like this:

public class Bravo : B
{
    public B method1() { return null; }
    public void otherMethod() { }
}

However, you can use the new keyword to shadow a method in an interface, but this isn't a great idea as it makes it harder to reason about your code as it breaks normal inheritance.

Try this:

public interface A
{
    A method1();
}

public interface B : A
{
    new B method1();
    void otherMethod();
}

public class Bravo : B
{
    A A.method1()  { return null; }
    public B method1() { return null; }
    public void otherMethod() { }
}
like image 50
Enigmativity Avatar answered Oct 31 '25 01:10

Enigmativity