[英]Return type of child class from parent class method
如果我有一个类A
以及从A
继承的类B
、 C
和D
,有没有办法在A
中编写一个方法,当在子类上调用时,该方法将具有子类的返回类型?
所以如果我做A.myMethod()
,我会得到一个A
,如果我做B.myMethod()
,我会得到一个B
的实例?
您要问的不是严格的多态性,因为您要覆盖返回类型,因此具有与原始方法不同的签名。 真正的多态不会改变这个签名,所以你问的不是 C# 中的一流情况。
话虽如此,至少有两种方法。
最简单的方法是覆盖方法,使用new
关键字隐藏原来的方法,让你改变签名。
public new B MyMethod() { return (B)(base.MyMethod()); }
这将允许B
任何用法返回B
,但实际上不会覆盖A.MyMethod
的行为。 避免代码中的重复类型转换很有用。
如果您还需要覆盖该方法以允许它返回类型B
的对象,则这不能共存于同一个类中,因为编译器看到相同的签名(相同的名称,相同的参数,即使返回类型显式不同) .
第二种方法称为Static Polymorphism ,如果您使用某种工厂,它非常有用,但可能非常棘手,因为它只允许一个级别的实际继承。 静态多态类型以具有约束自身的泛型组件的类型开始:
public class A<TSelf> where TSelf : A<TSelf> { }
public class B : A<B> { }
这意味着你的方法可以返回一个TSelf
类型的对象,甚至使它成为一个抽象方法,所以每个继承者都必须处理构造函数,但是从B
继承的任何类都很难覆盖它,因为它是从A<B>
继承的,不是A<C>
假设您只想在A
声明方法myMethod
,您可以执行以下操作:
namespace Test
{
class Program
{
static void Main(string[] args)
{
var a = new A();
var b = new B();
Console.WriteLine(a.M());
Console.WriteLine(b.M());
}
}
class A
{
public A M()
{
return (A)Activator.CreateInstance(GetType());
}
}
class B : A
{
}
}
印刷:
Test.A
Test.B
您所谈论的基本上是工厂方法/模式。 它有点偏离,因为创建自己的实例很奇怪。
但可以肯定的是,你可以这样写:
class A
{
public virtual A Create()
{
return new A();
}
}
class B
{
public override A Create()
{
return new B();
}
}
当然,返回类型必须保留为基类,但是由于您利用了多态性,这应该不是问题。
通常工厂方法会在另一个专门构建的类中,所以你知道。
是和否。考虑:
public class Parent
{
public int MyProperty { get; set; }
public virtual Parent MyMethod()
{
return new Parent();
}
}
public class A : Parent
{
public override Parent MyMethod()
{
return new A();
}
}
在 A 中,虽然返回类型是 Parent,但您返回的是 A。
如果您询问编译时间,则不能编写具有不同返回类型的覆盖方法。
但是在运行时是的,您可以并且您将拥有这些类型的实例,但是您必须编写代码以便具有“A”的返回类型,然后将它们转换为想要的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.