Can a child class implement the same interface as its parent?

11,317

Solution 1

You could, alternatively, do this one of two ways:

First, don't implement the interface explicitly:

public class Foo : IDispatch {
    public virtual void Dispatch() {
        whatever();
    }
}

public class Bar : Foo {
    public override void Dispatch() {
        whateverElse();
    }
}

Second, implement it explicitly but add a function that the child class can override:

public class Foo : IDispatch {
    void IDispatch.Dispatch() {
        this.Dispatch();
    }

    protected virtual void Dispatch() {
        whatever();
    }
}

public class Bar : Foo {
    protected override void Dispatch() {
        whateverElse();
    }
}

Solution 2

Yes, you can explicitly redeclare that you want to implement IDispatch, and implement it explicitly again in Bar.

However, you won't be able to call the original implementation in Foo. If you need to do that, you'll need to change Foo either to use implicit interface implementation with a virtual method (which can be overridden and then called with base.Dispatch() in Bar) or make the Foo implementation call a protected virtual method which again you'd override in Bar.

Solution 3

Bar already implements IDispatch if it is subclass of Foo, no need to explicitly state that. If you want to implement only one method of interface in a different way, do sth like this:

IDispatch { void Method(); }
Foo : IDispatch { public virtual void Method() { implementation1 } }
Bar : Foo { public override void Method() { implementation2 } }

Solution 4

You don't have to do the IDispatch.Dispatch - so long as a method called Dispatch is in your class you will have implemented the interface.

You can do this, it builds for me:

  public class Foo : IDispatch
  {
    public virtual void Dispatch()
    {
    }
  }
  public class Bar : Foo
  {
    public override void Dispatch()
    {
      base.Dispatch();
    }
  }
Share:
11,317

Related videos on Youtube

Jesse Carter
Author by

Jesse Carter

I tried so hard to steal the sky and call it heaven-bound...

Updated on September 29, 2022

Comments

  • Jesse Carter
    Jesse Carter over 1 year

    I've never encountered this issue before today and was wondering what convention/best practice for accomplish this kind of behavior would be.

    Basic setup is this:

    public interface IDispatch {
        void Dispatch();
    }
    
    public class Foo : IDispatch {
        void IDispatch.Dispatch() {
            DoSomething();
        }
    }
    
    public class Bar : Foo {
         ...
    }
    

    Bar needs to subclass Foo because it shares all the same properties as Bar plus introduces 2 new ones that I need to encounter for. The problem I have is that Foo also needs a slightly different implementation of Dispatch(). Normally it would be overridden but thats not valid for an interface method so is it fine to just have Bar implement IDispatch as well so my class definition looks like this:

    public class Bar : Foo, IDispatch { .... }
    

    and then just do an explicit implementation of that interface method in Bar as well? My compiler doesn't seem to complain when I try to do it this way but I wasn't sure if it would cause any runtime issues resolving which implementation to use down the road or if there was a better way to accomplish something like this.

    Also worth mentioning that at my workplace we use code generation from UML models which enforces that all class design must be done from a model first. The code generation tool is what causes interface methods to be implemented explicitly (don't want to debate the pros and cons of this its just what I'm forced to deal with right now so having an implicit implementation is not an option)

  • Jesse Carter
    Jesse Carter over 11 years
    Check the edit I made to my original post. This looks nice but I am unable to do it this way right now due to coding standards at my workplace
  • Jesse Carter
    Jesse Carter over 11 years
    Thanks for your help Jon. Just to be clear, Bar will never need to use Foo's implementation of Dispatch and vice versa. So in this case I should be fine given that they only care about their own implementation?
  • Jon Skeet
    Jon Skeet over 11 years
    @JesseCarter: No, because an instance of Bar is an instance of Foo. Do you really, really not want the implementation in Foo to be called when a client calls Dispatch on an instance which is a Bar? If so, should Bar really be derived from Foo in the first place? (It's unusual - though not unheard of - to completely replace an implementation like that.)
  • Olivier Jacot-Descombes
    Olivier Jacot-Descombes over 11 years
    A special intersting case is that you can let a derived class implement a method that was declared in the base class not implementing the interface: class A { public void Dispatch() {} } class B : A, IDispatch { }. (almost a corner case)
  • Jesse Carter
    Jesse Carter over 11 years
    @JonSkeet I cannot see any situation in which I would need Foo's implementation to be called when dealing with Bar. IDispatch are queued up in the system and when grabbed by a worker thread they call Dispatch which executes whatever code that class represents. If a Bar is dequeued I want it's implementation of Dispatch to be called not the implementation in its parent
  • Jon Skeet
    Jon Skeet over 11 years
    @JesseCarter: Again, that sounds like Bar probably shouldn't derive from Foo in the first place then.
  • Jesse Carter
    Jesse Carter over 11 years
    That very well could be, it just seemed like in this specific case Bar is a Foo given its properties and what it represents in the system so it seemed like unnecessary code duplication to have the 2 classes that were so similar
  • Jon Skeet
    Jon Skeet over 11 years
    @JesseCarter: Perhaps you should use composition instead of inheritance then - perhaps Bar should contain a Foo for the purpose of sharing implementation, but not try to pretend that it will act like a Foo.
  • Jesse Carter
    Jesse Carter over 11 years
    @JonSkeet Hmmm thats another great idea although I am leaning towards the second implementation mentioned by Rawling as it allows for the Dispatch method to be propery overridden by the child while preserving an explicit implementation of Dispatch in the parent
  • Jesse Carter
    Jesse Carter over 11 years
    Check the edit I made to my original post. This looks nice but I am unable to do it this way right now due to coding standards at my workplace
  • LukeHennerley
    LukeHennerley over 11 years
    @JesseCarter Rawlins answer looks like what your looking for, call an expose virtual method which isn't explicit to the interface and then override that
  • Jesse Carter
    Jesse Carter over 11 years
    Yah I am leaning towards that too. Seems like the cleanest solution given what I'm dealing with
  • Taterhead
    Taterhead almost 8 years
    in your "Second" comment - you mean derived instead of base, no?