views:

66

answers:

7

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.

A: 

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
A: 

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
I believe this works in Java as well.
BoltClock
I think the OP is talking about being able to force `public override void Method() {base.Method(); ...}`, not about constructors.
Ani
This only works for constructors, though.
Matti Virkkunen
@Ani, @Matti, yeah I misread construct as constructor :). Updated answer.
JaredPar
+2  A: 

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
+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
+2  A: 

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
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
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
A: 

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
+1  A: 

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
+1  A: 

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