2013-01-25 35 views
5

我想知道是否可以使用繼承類(它覆蓋方法)對象訪問基本虛擬方法。從繼承子類對象訪問父類虛擬方法

我知道這不是一個好的做法,但我想知道這一點的原因是,如果它在技術上是可行的。我不遵循這種做法,只是出於好奇而問。

我確實看到了一些類似的問題,但我沒有得到我正在尋找的答案。

實施例:

public class Parent 
{ 
    public virtual void Print() 
    { 
     Console.WriteLine("Print in Parent"); 
    } 
} 

public class Child : Parent 
{ 
    public override void Print() 
    { 
     Console.WriteLine("Print in Child"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Child c = new Child(); 
     //or Parent child = new Child(); 
     child.Print(); //Calls Child class method 
     ((Parent)c).Print(); //Want Parent class method call 
    } 
} 

請解釋downvotes。 在stackoverflow上的任何一個現有的類似問題的鏈接(令人滿意的答案)是可以接受的答案。 謝謝。

+0

我昨天幾乎回答了同樣的問題,在這裏; http://stackoverflow.com/questions/14491513/calling-both-base-and-derived-methods/14491581#14491581 –

+0

顯式調用父類Print()方法。顯然,正如你所指出的,這個架構試圖扭轉多態行爲 - 不是明智的 –

+0

@AdityaSihag;這對於重寫的方法不起作用。只有'new',按照上面的鏈接。 –

回答

4

按照鏈接複製我的評論,你可以用一些技巧反思這樣做:

static void Main(string[] args) 
{ 
    Child child = new Child(); 
    Action parentPrint = (Action)Activator.CreateInstance(typeof(Action), child, typeof(Parent).GetMethod("Print").MethodHandle.GetFunctionPointer()); 

    parentPrint.Invoke(); 
} 
+0

這就是我正在尋找的東西。感謝分享。 –

1

不能 - 調用基類的虛方法是不可能的 - 在這種情況下調用該方法的最派生實現。在你給出的例子中,它會在兩種情況下打印"Print in Child"

+0

-1;是的,根據上面發佈的重複鏈接。 –

+1

不是真的!在派生類中使用NEW關鍵字創建一個具有相同簽名的方法是將該方法隱藏或隱藏在基類中。這意味着您正在從派生類調用NEW方法,而不是從基類的方法。使您的打印語句與派生類的NEW方法具有不同的文字,並親自體驗它! –

1

據我,你能做的最好的是:

public class Parent 
{ 
    public virtual void Print() 
    { 
     Console.WriteLine("Print in Parent"); 
    } 
} 

public class Child : Parent 
{ 
    public override void Print() 
    { 
     base.Print(); 
     Console.WriteLine("Print in Child"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Child c = new Child(); 
     //or Parent child = new Child(); 
     child.Print(); //Calls Child class method 
     ((Parent)c).Print(); //Want Parent class method call 
    } 
} 
+0

這正是我的代碼。如果這樣做有效,我沒有理由問一個問題。 –

+0

請注意在Child class Print()中調用base.Print()。這將觸發對其基類Print方法的調用。 – mihirj

+0

對不起,我的壞。那麼,從孩子那裏調用基本方法並不是我的意圖。我想知道如果你不能對任何類進行任何代碼更改,技術上是否可行。但感謝您的答案。我很感激。 –

0

我不知道什麼時候這將是有益的。但是一個體面的解決方法可能是重載或編寫只調用父類的虛擬方法。這將是這個樣子:

public class Child : Parent 
{ 
    public void Print(bool onlyCallFather) 
    { 
    if(onlyCallFather) 
     base.Print(); 
    else 
     Print(); 
    } 
} 

然後在你的主要方法:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Child c = new Child(); 
     child.Print(false); //Calls Child class method 
     child.Print(true); //Calls only the one at father 
    } 
} 

所以它會做你想要做什麼。我已經看到了這種類型的解決方法,以告訴您是否需要調用基礎方法。