2017-09-13 92 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的实现。但没有实现,只是一个占位符。这就是为什么这是不被允许的。

相关问题