33

Is there a construct in Java or C# that forces inheriting classes to call the base implementation? You can call super() or base() but is it possible to have it throw a compile-time error if it isn't called? That would be very convenient..

--edit--

I am mainly curious about overriding methods.

irwinb
  • 993
  • 2
  • 10
  • 20
  • Do you mean from a constructor of when overriding a method? – munificent Oct 20 '10 at 22:04
  • I wish you had picked one language for your question - Java or C#. Just from the standpoint of making the question more useful to people that come later. Maybe the answer for Java is different than the one for C#. – Erik Hermansen Feb 01 '20 at 02:11

14 Answers14

24

There isn't and shouldn't be anything to do that.

The closest thing I can think of off hand if something like having this in the base class:

public virtual void BeforeFoo(){}

public void Foo()
{

this.BeforeFoo();
//do some stuff
this.AfterFoo();

}

public virtual void AfterFoo(){}

And allow the inheriting class override BeforeFoo and/or AfterFoo

MStodd
  • 4,716
  • 3
  • 30
  • 50
  • 7
    What you suggested seems to be the common solution the problem. Although having it force (or automatically call it) the inheriting class to call it would be convenient and would make certain errors easy to find. Could you elaborate on why there *shouldn't* be any feature does this? Does it go against basic polymorphism concepts and if it does, why? – irwinb Oct 21 '10 at 00:42
  • If I have a class that extends another class which is forcing me to call base.Foo() somewhere in my Foo, that's rather limiting. I either call base.Foo() if I want that functionality, or I can't use the class to extend mine. The compiler should enforce a minimal set of basic rules. You should check out code contracts for .NET http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx – MStodd Oct 21 '10 at 01:39
  • 8
    I don't see how its limiting, if you have a class that must call the base method thats a design choice, if the base method call is optional then you don't use the hypothetical keyword that forces a base call. In cases where the base method MUST always be called no exceptions i don't see how its limiting.. since the designer specifically chose it to be that way. – WDUK Jul 09 '18 at 05:10
  • 2
    "and shouldn't be anything to do that." Of course there should, just like abstract classes force overrides or interfaces force method implementation. It's a common need that would not muddy the waters if it was implemented. – John Stock Jan 11 '21 at 04:08
11

Not in Java. It might be possible in C#, but someone else will have to speak to that.

If I understand correctly you want this:

class A {
    public void foo() {
        // Do superclass stuff
    }
}

class B extends A {
    public void foo() {
        super.foo();
        // Do subclass stuff
    }
}

What you can do in Java to enforce usage of the superclass foo is something like:

class A {
    public final void foo() {
        // Do stuff
        ...
        // Then delegate to subclass
        fooImpl();
    }

    protected abstract void fooImpl();
}

class B extends A {
    protected void fooImpl() {
        // Do subclass stuff
    }
}

It's ugly, but it achieves what you want. Otherwise you'll just have to be careful to make sure you call the superclass method.

Maybe you could tinker with your design to fix the problem, rather than using a technical solution. It might not be possible but is probably worth thinking about.

EDIT: Maybe I misunderstood the question. Are you talking about only constructors or methods in general? I assumed methods in general.

Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86
  • 2
    +1: I don't think it's ugly. It's the template method pattern, and the proper approach. The name fooImpl() is ugly, but this is just an example... – Don Roby Oct 20 '10 at 22:31
6

The following example throws an InvalidOperationException when the base functionality is not inherited when overriding a method.

This might be useful for scenarios where the method is invoked by some internal API.

i.e. where Foo() is not designed to be invoked directly:

public abstract class ExampleBase {
    private bool _baseInvoked;

    internal protected virtual void Foo() {
        _baseInvoked = true;
        // IMPORTANT: This must always be executed!
    }

    internal void InvokeFoo() {
        Foo();
        if (!_baseInvoked)
            throw new InvalidOperationException("Custom classes must invoke `base.Foo()` when method is overridden.");
    }
}

Works:

public class ExampleA : ExampleBase {
    protected override void Foo() {
        base.Foo();
    }
}

Yells:

public class ExampleB : ExampleBase {
    protected override void Foo() {
    }
}
Lea Hayes
  • 62,536
  • 16
  • 62
  • 111
6

I use the following technique. Notice that the Hello() method is protected, so it can't be called from outside...

public abstract class Animal
{
    protected abstract void Hello();

    public void SayHello()
    {
        //Do some mandatory thing
        Console.WriteLine("something mandatory");

        Hello();

        Console.WriteLine();
    }
}

public class Dog : Animal
{
    protected override void Hello()
    {
        Console.WriteLine("woof");
    }
}

public class Cat : Animal
{
    protected override void Hello()
    {
        Console.WriteLine("meow");
    }
}

Example usage:

static void Main(string[] args)
{
    var animals = new List<Animal>()
    {
        new Cat(),
        new Dog(),
        new Dog(),
        new Dog()
    };

    animals.ForEach(animal => animal.SayHello());
    Console.ReadKey();
}

Which produces:

enter image description here

Fidel
  • 7,027
  • 11
  • 57
  • 81
4

You may want to look at this (call super antipatern) http://en.wikipedia.org/wiki/Call_super

Kemoda
  • 284
  • 1
  • 9
2

If I understand correctly you want to enforce that your base class behaviour is not overriden, but still be able to extend it, then I'd use the template method design pattern and in C# don't include the virtual keyword in the method definition.

Sebastian Piu
  • 7,838
  • 1
  • 32
  • 50
1

I didn't read ALL the replies here; however, I was considering the same question. After reviewing what I REALLY wanted to do, it seemed to me that if I want to FORCE the call to the base method that I should not have declared the base method virtual (override-able) in the first place.

Chris Barker
  • 21
  • 1
  • 6
1

No. It is not possible. If you have to have a function that does some pre or post action do something like this:

internal class Class1
{
   internal virtual void SomeFunc()
   {
      // no guarantee this code will run
   }


   internal void MakeSureICanDoSomething()
   {
      // do pre stuff I have to do

      ThisCodeMayNotRun();

      // do post stuff I have to do
   }

   internal virtual void ThisCodeMayNotRun()
   {
      // this code may or may not run depending on 
      // the derived class
   }
}
Russell McClure
  • 4,821
  • 1
  • 22
  • 22
1

Don't force a base call. Make the parent method do what you want, while calling an overridable (eg: abstract) protected method in its body.

Sentinel
  • 3,582
  • 1
  • 30
  • 44
0

I stumbled on to this post and didn't necessarily like any particular answer, so I figured I would provide my own ...

There is no way in C# to enforce that the base method is called. Therefore coding as such is considered an anti-pattern since a follow-up developer may not realize they must call the base method else the class will be in an incomplete or bad state.

However, I have found circumstances where this type of functionality is required and can be fulfilled accordingly. Usually the derived class needs a resource of the base class. In order to get the resource, which normally might be exposed via a property, it is instead exposed via a method. The derived class has no choice but to call the method to get the resource, therefore ensuring that the base class method is executed.

The next logical question one might ask is why not put it in the constructor instead? The reason is that it may be an order of operations issue. At the time the class is constructed, there may be some inputs still missing.

Does this get away from the question? Yes and no. Yes, it does force the derived class to call a particular base class method. No, it does not do this with the override keyword. Could this be helpful to an individual looking for an answer to this post, maybe.

I'm not preaching this as gospel, and if individuals see a downside to this approach, I would love to hear about it.

mschmit
  • 36
  • 2
0

Don't think there's any feasible solution built-in. I'm sure there's separate code analysis tools that can do that, though.

Matti Virkkunen
  • 63,558
  • 9
  • 127
  • 159
0

EDIT Misread construct as constructor. Leaving up as CW since it fits a very limited subset of the problem.

In C# you can force this behavior by defining a single constructor having at least one parameter in the base type. This removes the default constructor and forces derived types to explcitly call the specified base or they get a compilation error.

class Parent {
  protected Parent(int id) {
  }
}

class Child : Parent { 
  // Does not compile
  public Child() {}
  // Also does not compile
  public Child(int id) { }
  // Compiles
  public Child() :base(42) {}

}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • I think the OP is talking about being able to force `public override void Method() {base.Method(); ...}`, not about constructors. – Ani Oct 20 '10 at 22:04
  • @Ani, @Matti, yeah I misread construct as constructor :). Updated answer. – JaredPar Oct 20 '10 at 22:05
0

In java, the compiler can only enforce this in the case of Constructors.

A constructor must be called all the way up the inheritance chain .. ie if Dog extends Animal extends Thing, the constructor for Dog must call a constructor for Animal must call a constructor for Thing.

This is not the case for regular methods, where the programmer must explicitly call a super implementation if necessary.

The only way to enforce some base implementation code to be run is to split override-able code into a separate method call:

public class Super
{
    public final void doIt()
    {
    // cannot be overridden
        doItSub();
    }

    protected void doItSub()
    {
     // override this
    }
}

public class Sub extends Super
{
    protected void doItSub()
    {
     // override logic
    }
}
pstanton
  • 35,033
  • 24
  • 126
  • 168
0

On the Android platform there is a Java annotation called 'CallSuper' that enforces the calling of the base method at compile time (although this check is quite basic). Probably the same type of mechanism can be easily implemented in Java in the same exact way. https://developer.android.com/reference/androidx/annotation/CallSuper

AndrewBloom
  • 2,171
  • 20
  • 30