簡體   English   中英

從父類方法返回子類的類型

[英]Return type of child class from parent class method

如果我有一個類A以及從A繼承的類BCD ,有沒有辦法在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM