Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface + Extension (mixin) vs Base Class

Is an interface + extension methods (mixin) preferable to an abstract class?

If your answer is "it depends", what does it depend upon?

I see two possible advantages to the interface + extension approach.

  • Interfaces are multiply inheritable and classes are not.
  • You can use extension methods to extend interfaces in a non-breaking way. (Clients that implement your interface will gain your new base implementation but still be able to override it.)

I have not yet thought of a downside to this approach. There may be a glaringly simple reason that the interface + extension approach will fail.

Two helpful articles on this topic are

  • Create Mixins with Interfaces and Extension Methods
  • Abstract Base Classes Have Versioning Problems Too
like image 777
dss539 Avatar asked Apr 23 '09 20:04

dss539


People also ask

What is the difference between mixin and interface?

Mixins are hailed as interfaces with behavioral reuse, more flexible interfaces, and more powerful interfaces. You will notice all these have the term interface in them, referring to the Java and C# keyword. Mixins are not interfaces. They are multiple inheritance.

What is the difference between base class and interface?

An interface defines how other classes can use your code. A base class helps implementers to implement your interface.

What is the difference between a mixin and inheritance?

Mixins are sometimes described as being "included" rather than "inherited". In short, the key difference from an inheritance is that mix-ins does NOT need to have a "is-a" relationship like in inheritance. From the implementation point of view, you can think it as an interface with implementations.

What is the difference between a mixin and inheritance in Dart?

Mixins is not a way to get multiple inheritance in the classical sense. Mixins is a way to abstract and reuse a family of operations and state. It is similar to the reuse you get from extending a class, but it is compatible with single-inheritance because it is linear.


2 Answers

Downside of extension methods: clients pre-C#3/VB9 won't be able to use it as easily.

That's about it as far as I'm concerned - I think the interface-based approach is significantly nicer. You can then mock out your dependencies nicely, and everything is basically less tightly coupled. I'm not a huge fan of class inheritance unless it's really about specialization :)

EDIT: I've just thought of one other benefit which might be relevant. It's possible that some of the concrete implementations could provide more optimized versions of some of the general methods.

Enumerable.Count is a good example of this - it explicitly checks whether the sequence implements IList or not, because if it does it can call Count on the list instead of iterating through the whole sequence. If IEnumerable<T> had been an abstract class with a virtual Count() method, it could have been overridden in List<T> rather than there being a single implementation which knows about IList explicitly. I'm not saying this is always relevant, nor that IEnumerable<T> should have been an abstract class (definitely not!) - just pointing it out as a small possible disadvantage. That's where polymorphism really would be appropriate, by specializing existing behaviour (admittedly in a way which only affects performance instead of the result).

like image 102
Jon Skeet Avatar answered Sep 23 '22 02:09

Jon Skeet


IMHO, this is the wrong question.

You should use everything for what it is designed for.

  • Extension methods are not members. They are syntactically looking like members, so you can find them easier.
  • Extension methods can only use the public (or internal) interface. Many other classes could do the same. So extension methods are not a real encapsulation in an oo way.
  • They are static methods and can not be overridden and not be mocked in a unit test. Is is a non-OO language feature and the caller is statically bound to it.

  • Abstract base classes are really often misused to "reuse code" (instead of a real inheritance). This applies to inheritance in general.

The question should be: "When should I use Interfaces, extension methods or base classes?"

  • use interfaces whenever you need a contract (and this happens all the time).
  • Use (abstract) base classes when you have a situation for real inheritance (you could write a book about how to judged that, so I just leave it like this). An interface is mostly also implemented at the same time.
  • use extension methods for logic that should not be actually a member of the type, because it is not the responsibility of the type to implement it - but you want to make it easy to find and and it feels natural to call it like a member.

Edit:

Or the question should be: "How do I write reusable functionality that does not belong to a base class?"

  • write an interface that exposes the functionality
  • write a reusable library class that implements the functionality
  • write a class that implements the interface and reuses the functionality by aggregating the reusable class.

In general I would say, extension methods are the wrong place for business logic, except of special cases or special design decisions.

Base classes are only in rare cases the right decision. In doubt, it is not. In no-doubt, you should think again about it.

like image 22
Stefan Steinegger Avatar answered Sep 26 '22 02:09

Stefan Steinegger