Search code examples
c#overridingvirtualabstract

Is it possible to have an override method call its abstract virtual method?


My goal is to have the Abstract class update on its own once Consume is called on one of the derived classes.

Imagine this:

public interface IConsumable 
{
    void Consume();
}

public abstract class AbstractConsumable : IConsumable
{
    private bool _consumed = false;

    public virtual void Consume()
    {
        _consumed = true;
    }
}

public class HealthyConsumable: AbstractConsumable
{
    public override void Consume()
    {
        // Do something healthy and ...
        base.Consume(); // Would like to avoid this...
    }
}

public class PoisonousConsumable: AbstractConsumable
{
    public override void Consume()
    {
        // Do something poisonous and ...
        base.Consume(); // Would like to avoid this...
    }
}

What I would like to achieve here is not having to call base.Consume() on the override methods, but still have the abstract class set _consumed once the derived classes call their Consume() methods.


Solution

  • You could make Consume none virtual and within it you called another protected virtual (or abstract method) that can contain code that be change by sub classes. Consumers of your class can only call the public Consume method but this will intern call the sub class implementation specific code

    public interface IConsumable 
    {
        void Consume();
    }
    
    public abstract class AbstractConsumable : IConsumable
    {
        private bool _consumed = false;
    
        public void Consume()
        {
            _consumed = true;
            InternalConsumerBehaviour();
        }
    
        protected virtual void InternalConsumeBehaviour()
        {
             //default do nothing could potentially mark this method abstract rather than virtual its up to you
        }
    }
    
    public class HealthyConsumable: AbstractConsumable
    {
        protected override void InternalConsumeBehaviour()
        {
            // Do something healthy and ...
        }
    }
    
    public class PoisonousConsumable: AbstractConsumable
    {
        protected override void InternalConsumeBehaviour()
        {
            // Do something poisonous and ...
        }
    }