2017-09-13 57 views
0

比方說,我有這些類:我可以從另一個抽象派生類中的基類調用抽象方法嗎?

abstract class A 
{ 
    protected abstract void DoSomething(); 
    protected abstract void DoSomethingAnotherName(); 
} 

abstract class SuperA : A 
{ 
    private new void DoSomething() 
    { 
     base.DoSomething(); // <-- I can't do this. 
     DoSomethingAnotherName(); // <-- But I can do this. 
    } 
} 

sealed class FinalA : SuperA 
{ 
    protected override void DoSomething() { ... } 
    protected override void DoSomethingAnotherName() { ... } 
} 

我可以調用基類從另一個抽象類指定base關鍵字沒有鑄造抽象方法?我總是可以重新命名private new DoSomething方法並刪除base.部分,然後才能正常工作。但是如果我想要這種方法被命名爲這樣呢?

((dynamic)this).DoSomething() /* or */ ((FinalA)this).DoSomething() 

也不起作用,因爲在運行時該行的SuperA類內部運行,它可以看到它自己private DoSomething方法,所以有StackOverflowException

P.S.我並不需要它,我只注意到我的派生類中沒有新的私有方法。我的代碼與DoSomethingAnotherName方法類似。我只是很好奇,如果實際上在派生類中具有相同名稱的方法,可以運行此代碼。看來這是不可能的。

如果有人想描述CLR的功能,以及它是如何編譯成IL的,以及爲什麼它不可能 - 我會很感激這一點,我正在談論這個話題。對我來說,雖然抽象類聲明瞭抽象方法的「接口」,但我們無法從派生類型調用它,這似乎很奇怪。我知道我們不能創建抽象類,因爲它們還沒有實現。但是,當我使用派生類基地 - 這是顯而易見的,我跑已經已建成某處一個實例...

+0

抽象方法就是這樣 - 抽象。他們沒有定義,沒有實施。那麼你怎麼稱呼它?你做什麼,你會發生什麼? – ADyson

+0

@ADYSON你可以調用它,如果你不寫'''base.'''部分。你從另一個抽象類中調用它。當你實現最終的非抽象類編譯器時,確保你實現了這個方法(它在FinalA中實現)。 – EwanCoder

+1

您問「我可以調用指定基本關鍵字的基類抽象方法」。答案是否定的,因爲它是抽象的。如果你刪除了base,那麼它通常會在派生類中調用一些抽象方法的_implementation_。 – ADyson

回答

0

這會工作,但你必須把它從保護,以改變公衆

abstract class A 
{ 
    public abstract void DoSomething(); 
    protected abstract void DoSomethingAnotherName(); 
} 

abstract class SuperA : A 
{ 
    private new void DoSomething() 
    { 
     ((A)this).DoSomething(); 
    } 
} 

sealed class FinalA : SuperA 
{ 
    public override void DoSomething() { } 
    protected override void DoSomethingAnotherName() { } 
} 
1

我明白base關鍵字不正確。在這篇文章中給出了詳細的解釋:https://stackoverflow.com/a/3733260/3270191

所以沒有辦法從派生的抽象類中調用具有同名聲明方法的基類抽象方法。您應該重命名該方法才能在不使用base字的情況下調用此方法。

0

在抽象類中,所有抽象方法都在派生類中「等待」具體實現。他們只是佔位符,而不是更多。在A類中,DoSomething()也是如此,DoSomethingAnotherName()也是如此。

當您從派生的抽象類中的DoSomething()調用DoSomethingAnotherName()時,這是沒有問題的,因爲您仍然需要派生的非抽象類來實現DoSomethingAnotherName()。 SuperA.DoSomething()本身永遠不會被調用。 FinalA.DoSomething()可以被調用,但FinalA必須實現DoSomethingAnotherName(),所以清楚如果調用DoSomething()會發生什麼。

當您調用base.DoSomething()時,您明確指定不能使用派生類的實現,因此必須使用抽象類A的實現。但沒有實現,只是一個佔位符。這就是爲什麼這是不被允許的。

相關問題