Re: Abstract Base Classes vs Interfaces?

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



>Inline...
>
>Bob Powell [MVP]
>Visual C#, System.Drawing

A minor off-topic point, but putting text after your sig really screws
up newsreaders that are sig-aware.

<big snips ahead>

>On 2005-10-01, Bob Powell [MVP] <bob@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
>"david" <david@xxxxxxxxxxxxxxxx> wrote in message
>> On 2005-09-29, Bob Powell [MVP] <bob@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
>> Despite the documentations views Abstract classes and Interfaces are
>>> completely dissimilar and have very specific roles in an OO system.
>>
>> They really don't.
>>
>> Sure, there are circumstances where one or the other is the obvious
>> choice, and in those circumstances they do have specific roles. The
>> most obvious is mixin functionality which pretty much has to be defined
>> as an interface in .Net. Or when you want to provide a base
>> implementation, an abstract class is the only choice.
>>
>> But there's a lot of gray area in between those two, and a great many
>> situations where either would do just as well. And in those situations
>> choosing between the two can be tricky and subtle.
>
>It's true to say that the details are subtle and one can be substituted for
>the other in many sutuations however, there are very clear-cut reasons why
>one would chose an interface and reject an abstract class and vice-versa.

Before we get into this, I guess it might be nice to actually mention to
the OP reasons for choosing one or the other...

Advantages of abstract base class...
Can force base concrete implementation
Can allow default implemention
Easily extensible

Advantages of Interfaces
Doesn't force inheritance tree, can act as mixin
Fits well with "prefer composition to inheritance"
Not easily extensible.

Yes, I'm being a bit flippant with the "extensible" thing. But one
advantage of interfaces is that it defines a stronger contract. In
practice, this usually forces lazy programmers (like me) to think harder
during both design and maintenance.

We both agree on something later that I'll state upfront: when in doubt,
use an interface.



>>> An abstract class forces a specific chain of inheritance onto the classes
>>> that are derived from it. Effectively they say that if you want to play
>>> in
>>> my playground you MUST have this particular minimum concrete
>>> implementation.
>>> You MUST be a member of my family.
>>
>> That's kind of a strange definition of "concrete implementation", since
>> of course a pure abstract class has no implementation at all. I don't
>> *think* you're suggesting that one should never have a "pure" abstract
>> class (i.e., a class where all methods are MustOverride), but I'm not
>> sure from your post.
>
>Even a pure abstract class forces a specific type heirarchy.

True, my point though is that's not what is usually meant by "concrete
implementation", which has a very specific meaning. Base classes *can*
enforce a "concrete implementation", but they don't have to.


>>> Interfaces specifically enforce the method / property contract without
>>> enforcing the class derivation relationships. Effectively they say if you
>>> want to play in my playground I don't care who you are as long as you
>>> obey
>>> my rules. You can take any class and derive from it adding in an
>>> interface
>>> implementation. This is useful if you want to do something like enable
>>> third-party developers to adhere to rules in your application or system
>>> without necessarily providing them with a DLL or a concrete class from
>>> which
>>> to derive their own.
>>
>> OK, that eluded me. How does an interface let you do this? You still
>> need to provide third-party developers with a DLL to reference,
>> otherwise how are they going to implement the interface?
>
>This is the point. You absolutely do not need to provide a DLL or any
>concrete imlementation in order to hand an interface around to anyone who
>might wish to use it. Take for example a .NET implemented plug-in
>architecture. It is quite possible to define component interactions in terms
>of a set of interfaces and allow anyone to implement them using whatever
>concrete class heirarchy they think fit. As long as the contract of the
>interface is adhered to you never need to give a DLL, which may contain your
>valuable trade secrets, to a third-party.

I'm not sure here if we're being ambiguous about the meaning of
"interface", or if you or I are simply wrong about something. Usually
if you implement a .Net plugin architecture you deliver a DLL with your
interface in it and have others reference the dll and implement the
interface. This works identically with abstract base classes as well.
Usually this DLL doesn't have anything in it *except* the interface or
base class, so there's no issue with trade secrets.

There's a couple of alternatives, but I generally don't like either.
You could ask the client to create their own interface dll from a
definition you give them (although this requires strong naming be turned
off). Or you could publish a written spec of your "interface", then
load their plugin class and call all methods through reflection or late
binding.

Alternatively I suppose the interface could be a standard .Net interface
from the framework, but that's irrelevant here and you could of course
do the same thing with base classes anyway.

Did you have something else in mind? Am I missing something?

>>> .A good example of this is the ICollection interface
>>> that enables you to create a class that conforms to a specific contract
>>> yet
>>> doesn't have to be derived from any particular base class.
>>
>> Actually, I think ICollection is a good example of the ambiguity between
>> interfaces and abstract base classes. ICollection really cries out to
>> be an abstract base class with a built-in SyncRoot and a default
>> IsSynchronized implementation. But you can't do that in .Net because the
>> contract of ICollection is essentially a mixin pattern. So it has to
>> be an interface.
>>
>> That's the kind of design trade-off one comes across all the time. I'm
>> not disagreeing with any of your definitions above, I'm just saying that
>> choosing between the two is often quite tricky.
>>
>Architecture choice is almost impossible to get right first time and often
>refactoring rears its ugly head.

I actually think refactoring has a rather attractive visage :-)

But then, I'm kind of TDD-oriented.

> From experience I can say that I have had
>to refactor far less when I employed an interface based architecture than
>when I used a class-heirarchy. I don't say that Abstract classes are not to
>be used, just that the implications of using one enforces a pattern that
>becomes inflexible as soon as you chose that architecture.

Agreed.

PS. This is a very interesting and timely topic to me because this
weekend I need to decide between an interface and a base class for a
plugin system I'm writing. On the one hand I have a natural tendency
toward interfaces, on the other hand there's some default functionality
I'd like to enforce for performance reasons.


.



Relevant Pages

  • Re: Properties Shared Amongst Objects
    ... The host can query my application for certain ... In that context one usually strives to provide a subsystem interface that reflects the invariants of the DLL subject matter. ... A some point the conversion may become so complex that one wants to deal with it explicitly within the DLL subject matter. ...
    (comp.object)
  • Re: Explicit Linking of DLLs in VB.net
    ... yes this technique will only work on managed assemblys (exe or dll) ... "YourObject" is a form and is limited to the form methods. ... Wel implement propertys, methods, events in your interface and start ... Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Explicit Linking of DLLs in VB.net (attn Michel or any others)
    ... loads the dll and finds a form in the dll. ... Dim extForm As Form = extAssembly.CreateInstance("test.entry", ... Wel implement propertys, methods, events in your interface and start ... Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Problem marshalling interface pointer into local server
    ... It can be applied to the proxy/stub DLL as well. ... Mind you this is not the most efficient way of producing a DLL ... Now that would be correct - an Automation-compatible interface ... I had an issue where I have a in-proc server (server ...
    (microsoft.public.vc.atl)
  • Re: Implements Interface difference in VB IDE and Compiled version, is this a BUG!???
    ... You need to set binary compatibility to the compiled dll. ... > it seams that VB in IDE Runtime mode with ActiveX component doesn't ... > |> TLB file contains interface IWPSpecific, ...
    (microsoft.public.vb.general.discussion)