jtabuloc
jtabuloc

Reputation: 2535

What is the practical usage of interface not directly implemented in class?

I think I have a very naive question here that I didn't knew before that it was even possible. Forgive me if my title question is a bit vague because I don't even know how to describe it. Here is the code that looks weird to me.

public interface IMyInterface
{
    void ImplementMe();
}

public class StandAlone
{
    public void ImplementMe()
    {
        Console.writeline("It works!");
    }
}

public class SubClass : StandAlone, IMyInterface
{
    // no need to implement IMyInterface here but it still work!!!
}

IMyInterface myInterface = new SubClass();
myInterface.ImplementMe();   // Output : "It works!"

I just want to know the following :

Upvotes: 4

Views: 484

Answers (4)

Matías Fidemraizer
Matías Fidemraizer

Reputation: 64933

Not all classes are direct implementations of interfaces.

For example, let's put a good sample based on a simple class inheritance:

public class Person 
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string LastName { get; set; }
}

public class Employee : Person
{
}

Now, let's imagine that we need to store uniquely-identifiable objects in some common store where we don't care about the entities' types but just about they're uniquely-identifiable.

BTW, we consider that persons shouldn't be stored within such store, because they're not valid entities within our organization but they're just there to improve code reusability and don't repeat ourselves.

So we define an interface like this:

public interface ICanBeUniquelyIdentifiable
{
     Guid Id { get; set; }
}

...and we don't implement it on Person but we do so on Employee:

// Now an employee is an actual object that can be uniquely identifiable,
// and this isn't true because Person has an Id property, but because
// Employee fulfills the contract!
public class Employee : Person, ICanBeUniquelyIdentifiable
{
}

Background

I would say that your reasoning should be that you implement interfaces where they really matter to be implemented, and reusability shouldn't be the key point when implementing interfaces.

Actually, you should implement interfaces on objects which should be accepted on some API and you just need a subset of the full type of a given object.

Upvotes: 0

Luaan
Luaan

Reputation: 63722

But SubClass does implement the IMyInterface - it has all the required public members with the right signatures. There's no specific terminology since there's nothing weird about it.

In fact, some languages take this even further, and allow you to cast any object to an interface, as long as the class has the right members (and in yet more flexible languages, even if it doesn't).

The main benefit is again the same as any other way to use interfaces - it allows you to abstract the implementation away from the interface. It's just a shortcut to having to do an explicit interface implementation, something like:

class SubClass : BaseClass, IInterface
{
  void IInterface.MyMethod()
  {
    base.MyMethod();
  }
}

You might think that you could just implement the interface in the base class, but there's plenty of reasons why you wouldn't:

  • You don't want to maintain a public interface for the base class, it's just an internal class that shouldn't be exposed outside.
  • You don't have a way to change the base class to include the interface, so if you want to keep an inheritance chain, you must subclass and add the interface to the subclass.
  • The inferface contains some members that aren't contained in the BaseClass.

You'll probably find a couple more reasons if you try.

But the main point is: why not? You need a reason to do something (expand the definition of the base class instead of just the subclass). Adding abstraction everywhere along your codebase is rarely beneficial - you're trying to find a good trade-off between clarity of intent and clarity of implementation. An interface on a base class might help or hinder that.

Upvotes: 3

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236208

Well, first case that comes to my mind - when you don't own source code of StandAlone class, but later you decided to introduce interface which describes behavior of StandAlone class. E.g. for unit-testing (it's not best practice to mock code which you don't own, but sometimes it might be helpful) or you want to provide alternative implementation of StandAlone behavior in some cases. So either you have no options for unit-testing such code:

public class SUT
{
    private readonly StandAlone dependency;

    public SUT(StandAlone dependency)
    {
        this.dependency = dependency;
    }

    // ...
}

But if you'll introduce interface, you can actually switch to dependency from IMyInterface instead of StandAlone. And provide SubClass as implementation of interface with zero efforts.

public class SUT
{
    private readonly IMyInterface dependency;

    public SUT(IMyInterface dependency)
    {
        this.dependency = dependency;
    }

    // ...
}

Upvotes: 6

Jamiec
Jamiec

Reputation: 136094

One legitimate use of this pattern (Outside of simply the original programmer should have put the interface on the base class) could be that Standalone is in a 3rd party (or inaccessible) assembly, and IMyInterface was written in your own code to provide a Facade.

Consider this;

  • Your app wants to provide some functionality. You define an interface with method ImplementMe.
  • Standalone is in ThirdParty.dll and provides this exact method name (Perhaps you modelled your interface on that method name on purpose)
  • You subclass Standalone within your own code in order to implement your functionality.
  • Maybe you have a second way of implementing ImplementMe for which you have your onw class implementing your own interface. (public class MyOwnImplemetation : IMyInterface {... })

You could then use DI to instantiate the correct implementation of StandAlone or MyOwnImplemetation but treat them both as IMyInterface.

Upvotes: 2

Related Questions