简体   繁体   中英

Call child implementation of abstract class type C#

I want to call the child class implementation on an object with the abstract class type. However, this doesn't work the way I thought it would. Is there a way to do it, that doesn't require me to switch between types in the second switch satement? Or does C# not allow for this type of behavior?

The code where it is called:

AbstractParentType wfp;

//Switch on diagram type and select processor
switch (qi.DIAGRAMTYPE)
{
    case 1:
        wfp = new T1(notifications);
        break;
    case 2:
        wfp = new T2(notifications);
        break;
    case 3:
        wfp = new T3(notifications);
        break;
    default:
        throw new Exception("Diagramtype not implemented");
}

bool result = false;
//Switch on action type
switch (qi.Type)
{
    case (int)WorkflowActionType.BelItem:
        //Do some case specific stuff here
        ...
        //Call method
        result = wfp.Meth1();
        break;
    ... (a bunch of cases) ...
    case (int)WorkflowActionType.WordDocument:
        //Do some case specific stuff here
        ...
        //Call method
        result = wfp.Meth10();
        break;
}

Then we have the classes implementations:

abstract class AbstractClassType {
     public bool Meth1() { ... }
     ...
     public bool Meth10() { ... }
     ...
     public abstract MethX();
     public abstract MethY();
}

class T1 : AbstractClassType  {
     public new Meth1() { ... }
     ...
     public new Meth10() { ... } 
     ...
     public override MethX() { ... }
     public override MethY() { ... }
}

The actual methods do have parameters and I do want a base implementation for some of the methods (but not all of them). The goal is to allow the inherting classes to 'extend' the methods behavior.

Try using the virtual keyword

When using virtual, you can give methods in the base class a 'default' implementation. Like so:

abstract class AbstractClassType {
    public virtual void MethX(){
        //default implementation here.            
    }
    public virtual void MethY(){
        //another default implementation here!
    }
}

class T1 : AbstractClassType {
    public override void MethX(){
        //base.MethX() would call the logic in the base class. 
    }
    public override void MethY(){ 
        //base.MethY() would call the logic in the base class. 
    }
}

The difference between virtual and abstract is that basically, an abstract method cannot have a base implementation, and must be overridden.

A virtual method can have a base implementation, and does not need to be overriden.

You're not required to call base.MethX/Y() . You could even give the method a whole new meaning if you wanted to.

First of all, you cannot create an object of an abstract class as it is not really a complete entity. You will always need to instantiate the object of a class that extends the abstract class.

Following code shows various, not all, options you have when working with abstract classes.

    public abstract class AbstractClass
    {
        public void OnlyInAbstract() {
            Console.WriteLine("You are stuck with OnlyInAbstract in abstract class unless you use new keyword.");
        }

        public virtual void OnlyInAbstractForNow()
        {
            Console.WriteLine("You have reached abstract class for now. However, override me for changed behaviour.");
        }

        public abstract void MustImplement();
    }

    public class FirstChild : AbstractClass
    {
        public override void MustImplement()
        {
            Console.WriteLine("You called MustImplement in FirstChild. Nothing else to see here.");
        }

        public override void OnlyInAbstractForNow()
        {
            base.OnlyInAbstractForNow();
            Console.WriteLine("I see you changed my behaviour in FirstChild to extend it after abstract class was done with.");
        }

        public new void OnlyInAbstract()
        {
            Console.WriteLine("Looks like we are making an all new OnlyInAbstract method in child class.");
        }
    }

    static void Main(string[] args)
    {
        AbstractClass abstractClass = new FirstChild();

        abstractClass.MustImplement();

        abstractClass.OnlyInAbstract();

        (abstractClass as FirstChild).OnlyInAbstract();

        abstractClass.OnlyInAbstractForNow();

        Console.Read();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM