在重写期间将返回类型更改为派生类型

Joh*_*per 4 c# inheritance encapsulation class

我想要一个接口 A。这将允许类型 A 的对象生成类型 A 的其他对象。我需要类型 B 的相同行为。在我的应用程序中,所有 B 也是 A。所以我希望 B 成为源自 A。

这是我的尝试:

public interface A {
    A method1();
}
public interface B : A {
    overrride B method1();
    void otherMethod();
}
Run Code Online (Sandbox Code Playgroud)

请注意,override 关键字此处无法编译。使项目编译的唯一方法是使接口 B 如下所示:

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

然而我想通过接口 B 承诺,这种类型的对象有方法生成 B 类型的其他对象。

接口 B 的实现可能如下所示:

class Foo : B {
    B metod1();
}
Run Code Online (Sandbox Code Playgroud)

我想要从接口 BB metod1()实现B method1(),并且还希望从接口 A 实现相同的方法。A method1()我希望实现接口 B 的所有类都有相同的行为。所以我不想每次都实现 method1 两次两个接口。

我在 C# 中使用接口执行此操作。但我相信,即使对于类,甚至在 Java 中,类似的问题也可能很有趣。

Eni*_*ity 5

正确执行此操作的唯一方法是使用如下泛型:

public interface A<T> where T : A<T>
{
    T method1();
}
Run Code Online (Sandbox Code Playgroud)

然后B看起来像这样:

public interface B : A<B>
{
    void otherMethod();
}
Run Code Online (Sandbox Code Playgroud)

最后,实现一个类将如下所示:

public class Bravo : B
{
    public B method1() { return null; }
    public void otherMethod() { }
}
Run Code Online (Sandbox Code Playgroud)

但是,您可以使用new关键字来隐藏接口中的方法,但这不是一个好主意,因为它会破坏正常的继承,从而使您的代码更难以推理。

尝试这个:

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() { }
}
Run Code Online (Sandbox Code Playgroud)