2

I'm writing an app it needs to have generic registration step item. It needs to be able to do some specific things (I use interface for that) and it needs to be a visual element (of Xamarin. It doesn't really matter, though), say VisualElement (I use abstract class for that). This is how it all looks like:

public interface IRegistrationStep
{
    Task<bool> Validate();
    void Minimize();
    void Maximize();
}

public abstract class RegistrationStep : ContentView, IRegistrationStep
{
    public abstract Task<bool> Validate();
    public abstract void Minimize();
    public abstract void Maximize();
}

After that, I derive all my steps from RegistrationStep. If I need the step to be able to do one more thing, I simply add it to the interface, add abstract method to abstract class and implement it in the abstract class implementation... Or maybe not? Like, maybe sometimes I should add methods only to the abstract class and not to the interface?

My question is, how do I decide where to add new methods? Are there examples when its more reasonable to add methods to abstract class and not to the interface?

6
  • 1
    Related, but not a dupe: programmers.stackexchange.com/questions/41740/…
    – Doc Brown
    Sep 15, 2016 at 7:59
  • @gnat: that other title looks like a dupe of this one at a first glance, but the actual question is quite different. In that other question, the abstract class is not necessarily derived from the interface in stake. I was also thinking there must a dupe somewhere here on Programmer's, but I could not quickly find a real one, only red herrings.
    – Doc Brown
    Sep 15, 2016 at 8:11
  • @DocBrown, You are right. I automatically read it as IContentView. :) My comment was pointless therefore.
    – David Arno
    Sep 15, 2016 at 8:21
  • Is there any need for the RegistrationStep class? Since none of its methods are implemented, it provides nothing that IRegistrationStep doesn't, aside from inheriting from ContentView.
    – Dan Lyons
    Sep 15, 2016 at 17:38
  • @DanLyons is there any need for the IRegistrationStep interface if it is only ever (directly) implemented by RegistrationStep?
    – Caleth
    Feb 8, 2019 at 16:34

3 Answers 3

4

Apply the YAGNI principle: if it is sufficient to add the new method to the abstract class, add it only there - do not add anything to IRegistrationStep "you are not going to need (yet)". But if you have code which has a dependency on IRegistrationStep and which is going to use the new method, then you obviously need to add it in both places.

3

In general, extending an interface is not a good idea. An interface should offer a single distinct functionality. If you need more later you should define an additional interface and implement that as well in your class.

Do you have a good reason to use interfaces? Do you expect to want and implement that interface on other classes that do not inherit from the same base class RegistrationStep inherits from? If not, there is probably no added value and you would be better off not using interfaces at all.

The name of your interface is not so nice. An interface defines behavior, not an object. That is why you will see names like IEnumerable and IDisposable rather than IEnumerator or IDisposer. Likewise, yours should be named IRegistrationSteppable. If that feels weird, that may just be another indicator interfaces are not appropriate for your problem.

2
  • 1
    Indeed, I tend to find whenever I see "IClassName" (or "InterfaceNameImpl" it's a pretty sure sign the person is using an interface just because they think they are supposed to rather than for a concrete reason Sep 15, 2016 at 14:40
  • An interface prescribes a minimal set of requirements of an object, which may include state besides behavior. IEnumerable and IDisposable define 'secondary' behaviors, while IEnumerator defines the main purpose of the implementing object. Here I find IRegistrationStep more appropriate (although I agree with you no interface is needed at all).
    – Philippe
    Sep 18, 2016 at 17:45
0

The hard requirement for interfaces comes when you have to inherit from more than one thing.

(C# won't let you inherit from more than one class as this can cause some interesting ambiguity about what method to call in some edge cases)

So, say you have a ConcreteRegistrationStep which you want to inherit from the abstract but also implement some other functionality, say IDisposable. The fact that there is an IDisposable interface rather than an abstract class allows you to do inherit the interface and then be able to cast ConcreteRegistrationStep to a disposable.

Taking this logic further you can see that having an IRegistrationStep and using this in code which consumes RegistrationSteps rather than the abstract class will allow you or others more flexibility in future.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.