Ivan Zyranau
Ivan Zyranau

Reputation: 941

Can I call abstract method from base class in another abstract derived class?

Let's say I have these classes:

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() { ... }
}

Can I call base class abstract method from another abstract class specifying base keyword without casting? I can always rename private new DoSomething method and remove base. part, then it works. But what if I want this method to be named like this?

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

also doesn't work since at runtime this line runs inside the SuperA class and it can see it's own private DoSomething method, so there's StackOverflowException.

P.S. I don't really need it, I just noticed that I have no new private methods in my derived class. My code is like with DoSomethingAnotherName method. I just got curious would it be possible to run this code if there actually was a method with the same name in a derived class. And it seems like it's not possible.

If anyone feels like describing what CLR does and how it is all compiled to IL and why it can't be possible at all - I'll appreciate this, I'm into the topic. To me it seems strange though that abstract class declares an "interface" of abstract methods and we can't call it from derived types. I understand that we can't create abstract classes since they are not implemented yet. But when I use base from derived class - that's obvious that I run an instance that already has been constructed somewhere...

Upvotes: 2

Views: 3192

Answers (3)

Thern
Thern

Reputation: 1059

In an abstract class, all abstract methods "wait" for a concrete implementation in a derived class. They are just placeholders, not more. So is DoSomething() in class A, and so is DoSomethingAnotherName() as well.

When you call DoSomethingAnotherName() from DoSomething() in a derived abstract class, this is no problem because you still need a derived non-abstract class to implement DoSomethingAnotherName(). SuperA.DoSomething() itself will never be called. FinalA.DoSomething() can be called, but FinalA must implement DoSomethingAnotherName(), so it is clear what happens if DoSomething() is called.

When you call base.DoSomething(), you explicitly specify that no implementation of the derived class may be used, so the implementation of the abstract class A must be used. But there is no implementation, just a placeholder. That is why this is not allowed.

Upvotes: 0

Ivan Zyranau
Ivan Zyranau

Reputation: 941

I understood base keyword incorrectly. Detailed explanations are given in this post: https://stackoverflow.com/a/3733260/3270191

So there's no way to call base class abstract method from derived abstract class that has method with the same name declared. You should rename the method in order to call this method without the base word.

Upvotes: 1

Yair Halberstadt
Yair Halberstadt

Reputation: 6891

This would work, but you'd have to change it from protected to public

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() { }
}

Upvotes: 0

Related Questions