none
Discussion: Should Interfaces be replaced by multiple inheritance? RRS feed

  • General discussion

  • I'm interested to see what people think of this. It's not new to suggest that an interface can be replaced with an abstract class or that multiple inheritance can be complicated. But would the advantages of not necessarily requiring the 'implementing' classes to recompile when an addition method/property is added to the base class outway the added complexity?

    http://pdkm.spaces.live.com/
    • Changed type pkr2000 Monday, July 6, 2009 6:22 AM
    Monday, July 6, 2009 6:21 AM

All replies

  • Hey!

    Long time no speak!

    MY answer - no they shouldn't.  They don't do the same thing.

    An interface does not have implementation, so in that way has a different use to an abstract class.
    I ALWAYS use an interface, and if there is base implementation, I will create an abstract base class that implements such an interface.  If you reference the abstract class directly, then the close will be closely coupled to a concrete implementation, which you don't want.  You should always reference using the interface, regardless of whether an abstract base class is being used or not.  The case in point here revolves around the question, if the base class changes, that forces a complete recompile, whereas a base class can implement a new interface so that old clients can still access the backward compatible interface implementation, and new clients can use the new one. 
    Another thought you have to consider is, what happens if the base class changes?  Using an interface would mean that it doesn't matter, using the base class means that you are bound now to the new version of the class.  This leads to a ripple effect in the solution - one small change can break the application easily, and potentially may have to implement calls based on assumptions of implementation in the base class.  Using an interface means you cannot make any assumption based on implementation details, since the interface does not define them.

    No interfaces = bad.
    Abstract base classes = okay, in the right scenario.

    Good to hear you're still around!

    Martin.
    MCSD, MCTS, MCPD. Please mark my post as helpful if you find the information good!
    Monday, July 6, 2009 10:35 PM
  • I'd like to add that you can consider using extension methods where appropriate.  Extension methods extends can extend the class, but will of course not change it or force a recompile of that class.

    I do agree that Interfaces are very useful and should be used, but that said, I've experienced before that even if you implement interfaces, when you change the class, it can still lead to bugs.  Perhaps the new implementation is expecting the methods to be called in a certain order, a restriction that the original class might not have had.  What do you think, Martin?

    I haven't really used multiple inheritance before, since C# doesn't allow it, but if one does, how would you know what the base class is?  Would that not create problems?

    Kind regards,
    - Iwan
    Tuesday, July 7, 2009 8:16 AM
  • re: Iwan
    IMO my jury is out on extension methods, I still worry they muddy the OO waters too much, but yes they could be used to "travel" to each client and add a new reference to your new feature DLL. re: Multiple inheritance, yes as I mentioned they become complicated which is probably one of the reasons it isn't followed in .net.

    re: Martin
    Yes Hi, I see you're still giving great advice :)
    I admit I'm playing devil’s advocate a bit here, but from my point of view it comes down to this...
    Abstract classes (without specific interface) are great when you're *adding* new features and don't wish the clients to recompile. So for example you could add a new LogImportant method to a logger and the clients may or may not choose to make use of it but none of the existing code will break. This is the technique the .net framework turned to (according to the MS framework book). One obvious flaw with this is you can only derive from one class hence the idea of multiple inheritance. Conversely when is a thing a thing? If I derive from one of my Logger clients and call LogImportant is the "default" behaviour correct, and what do I mean by default? Who is implementing it in the derivation chain?

    re: coupling. I'm not sure I agree that you need interfaces to (help to attempt to) prevent coupling. Ultimately you have to reference a DLL with the description of the contract, be that abstract class or interface. Typically today the vogue is use some form of IOC/Factory to serve up the specific instance of a component implementing the contract, so the reference coupling strain is taken up by whatever framework is doing that role.

    re: the dreaded ripple effect. If an abstract class changes its existing API then the clients would have to be recompiled. If an interface changes its existing API then the clients would have to be recompiled. So by convention you don't change the interface you create a new one, so why not do the same with the abstract class? Well cause you don't have multiple inheritance is one very obvious reason ;)

    There is also another pragmatic issue when it comes to changes. When you change an interface/contract/abstract class how many variants do you actually live with? From a support view I'm itching to get rid of the old ones ASAP. In reality I want the clients to stop using the old contract and not all projects expose their interfaces to the public so it isn't that much of an issue to refactor.


    http://pdkm.spaces.live.com/
    Tuesday, July 7, 2009 8:42 AM
  • It's a design principle to use interfaces when the behavior changes i.e. the implementation details are different for same method in difefrent classes. Go for abstract class route if the behaviour does not change and remain same for all the methods.

    Example:

    TakeBreathe() is the behaviour that remains same in all living things while MakeNoise() is not. All living things take breathe in the same way but they make noise difefrently i.e. dogs wark, cat miows etc.

    So, in this case go for an interface for defining MakeNoise() behaviour while implement the TakeBreathe() in the base class which the animal class inherits from


    Hope this helps you in decision making....

    Vinod
    Wednesday, July 8, 2009 7:31 AM
  • pkr2000!

    You playing devils advocate?!  Really?!!

    I agree that you can use inversion of control, but if you include the reference to the class  rather than the interface then potentially you can be bound the implement.
    A short example, which is the best return type, ICustomerCollection or List<Collection>?  That's an easy one, right?  What if I want to change to using a Collection, or a Dictionary, or something custom behind the scenes.  I've done this a lot of times, and been glad that I had an interface through which the data was returned.

    I don't follow the default logic at all?  How can you call a default on something, or are you talking VB here?

    The coupling scenario - I'd agree to an extent about IoC, it is a good point.  I still think that Abstract classes referencing other abstract classes is easier to get into strife simply because you can put implementation into the contract, whereas an interface makes no assumptions at all about the contract, other than actually how you you a particular call.  That means it is a cleaner separation, which in turn equates to a looser coupling of code.

    The difference re: ripple - if the implementation of the abstract class implementation changes, a recompile would be necessary (unless you switch off versioning on the references, which surely you'd want?)  If you have an interface, unless you're making a major breaking change, i.e. a change to the way that you talk to the implementation, a recompile is not necessary.  All code suffers from major breaking change, but I would also submit that these are not dreaded, after all most of us would be out of a job if they did not occur.  Late binding would be the only way to get around these, and to be honest, I been there got that t-shirt already!  The versioning of abstract classes would be increased potentially if the implementation changes, without the contract for communication changing, so this seems a little like a compromise to lose some of the early bound checking, and have overhead potentially for versioning when you don't really need it?

    Here's the thing - re obsoleting old interfaces (interface or abstract class) - if you're calling through a Factory, and facade, and returning the correct version, it seems a pretty easy task to check how often the obsolete interface method is used, if not many, retire the interface, and force the upgrade.  Here's another suggestion, mark the members of the class / interface with [Obsolete], that stops people using it pretty quickly....  Regarding exposing interfaces to the public - I don't think that's a biggie, if the factory is also public, then you obsolete the methods that return through the interface, as that interface will be useless being used anyway...

    Good to hear from you anyway!  Keep up the good work.

    Martin.
    MCSD, MCTS, MCPD. Please mark my post as helpful if you find the information good!
    Wednesday, July 8, 2009 8:11 AM
  • Hi Vinod, imagine a situation where there wasn't a concept of interfaces. If you have multiple inheritance and used abstract classes how would your advice change?
    http://pdkm.spaces.live.com/
    Wednesday, July 8, 2009 10:24 AM
  • Martin, 

    re: example: yes there is a risk that by not using pure abstract classes your end up with bound to an implementation. But if you do use pure abstract then you should be ok(?)

    re: default: Yes that was poorly worded. What I'm talking about is that when you call a new method and simply pass on the call to your base class. If that class changes then your clients would hold "you" responsible, i.e. you're relying on some other implementations default behaviour.

    re: Versioning, I'm being dumb I don't follow how that's different?

    re: Obsolete: Yes and that's what you should do, but that doesn't differ between interface or abstract class. I'm was suggesting that the argument for leaving old contracts around may not, in the real world, be needed in many cases where you can refactor the code at both ends of the contract.

    re: Coupling: I guess this is the crux of the argument. With an abstract class there is the temptation to change it in the future, but I wonder if that's reason enough to have interfaces? The bottom line for me is there is no difference between a pure abstract class and an interface... apart from the restrictions placed upon inheritance. To defend interfaces I would say that it's hard to see how you can add a new method to a base class, to make it available, but also make it a purely abstract change. Someone will have to change to implement it.




    http://pdkm.spaces.live.com/
    Wednesday, July 8, 2009 10:36 AM
  • A quick background post on the subject of .net multiple inheritance
    http://pdkm.spaces.live.com/
    Sunday, July 12, 2009 4:54 PM
  • i give you a conceptual answer,

    when ever you define a functionality that may be need to use in many class or struct you must define this functionality by interfaces,

    every body think that interface isn't any thing more than a set of public abstract methods or a extra work for  declare a method.

    i sure you  they are in mistake.

     

    by interface you can iterate in many  objects that those are different in class types but those are  homogeneous in implementation of specific interface.

    this flexibility also allow you to categorize some object that are different in types in one set and iterate them and cast them to their class type

    for example:

    class A:IMyInterface { }

    class B:IMyInterface { }

     

    //********* you can do these castings

    A myAClass = new A();

    B myBClass = new B();

    IMyInterface[] C={A,B};  // initialize and casting;

     

    foreach(IMyInterface c in C)

    {

    if( c is A)

    {

        A newAClass= (A)c; // recover A

    }

    else if (c is B)

    {

       B newBClass=(B)c;  // recover B

    }

    }

    //************************

     

    i repeat this again that whenever you define a functionality that may be need to use in many class or struct you must define this functionality by interfaces,

    i think interface is replacement for multiInheritance in best and categorized way

     



    va-ansari
    Tuesday, November 9, 2010 12:02 PM
  • I think there's black white and grey areas.

    Where you have multiple object/classes that are going to have the same methods but they do different things then interfaces are clearly the thing to use.

    Where you have a hierarchy where you can see a core of methods but many have extra fiddly bits on them then inheritance is clearly the thing to use.

    Inbetween and in that grey area there's no "right" answer.

    Overhead in recompiling is rarely going to be worth factoring.

    I've seen code where people unthinkingly applied the one true pattern to everything.  It wasn't pretty.

    Wednesday, November 10, 2010 1:47 PM
  • In my case, i like to use interfaces, because is more escalable in a lot of cases,

    in a accounting project, I use a Icontable interface with the follow structure

    using System.Xml;
    
    namespace Accounting.BLL
    {
      public interface IContable
      {
        /// <summary>
        /// Crea el Mensaje contable
        /// </summary>
        /// <param name="appCodi">Codigo de la aplicacion origen que solicita la contabilizacion</param>
        void setMensajeContable(string appCodi, ENTOperacionContable objOperacionContable, string user);
        /// <summary>
        /// Metodo que hace llamado al webservices contable
        /// procesa la informacion y 
        /// </summary>
        /// <returns>Mensaje de respuesta </returns>
        XmlDocument doContabilizacion();
        /// <summary>
        /// Obtiene la informacion de los Documentos contables procesados
        /// </summary>
        /// <param name="appCodi">Codigo de la aplicacion que realiza la solicitud</param>
        /// <param name="tipoOperacion">Codigo del tipo de operacion que filtra la solicitud de la aplicacion</param>
        /// <returns></returns>
        XmlDocument getProcesadas(string appCodi, int tipoOperacion);
        /// <summary>
        /// Obtiene el numero de comprobante generado por Seven
        /// </summary>
        /// <param name="appCodi">Codigo de la aplicacion que realiza la solicitud</param>
        /// <param name="tipoOperacion">Codigo del tipo de operacion que filtra la solicitud de la aplicacion</param>
        /// <param name="mco_nume">Identifiacion del documento</param>
        /// <returns></returns>
        XmlDocument getComprobante(string appCodi, int tipoOperacion,int mco_nume);
      }
    }
    
    

    and everyone class that like implement account movement, are there


    Leonardo Romero Castro
    Wednesday, November 10, 2010 8:01 PM
  • The question is about the difference between Interfaces and Abstract Classes *IF* multiple inheritance was available. It is not a question of, "are interfaces useful"? Thanks.

     

     


    http://pdkm.spaces.live.com/
    Thursday, November 11, 2010 5:33 PM
  • Interfaces add another layer of abstraction between implementation. 

    The real problem is that inheritance is a 'IS-A' relationship, while I think of interfaces as a 'I-Support-This-Functionality' relationship.

    If you don't have interfaces, then you are constrained a bit in how you support something: you have to inherit.  interfaces allow you to support things by inheritance (if your base class inherits all of the interfaces) or composition (meaning that you inherit the interfaces, but can do composition to implement the funcitonality).

    Thursday, November 11, 2010 10:12 PM
  • Phillip, yes that is a good point but if you only used abstract classes then you'd get the same result. So my argument would be if you wanted to just be a 'supporter of' then you'd derive from the abstract class, but if you did fancy picking up some base behaviour then you'd derive from something 'lower' down the stack.
    http://pdkm.spaces.live.com/
    Friday, November 12, 2010 2:56 PM
  • Contrasting Interface Types to Abstract Base Classes
    the interface type may seem very similar to an abstract base class.
    Recall that when a class is marked as abstract, it may define any number of abstract members to
    provide a polymorphic interface to all derived types. However, even when a class type does define a
    set of abstract members, it is also free to define any number of constructors, field data, nonabstract
    members (with implementation), and so on. Interfaces, on the other hand, only contain abstract
    members.
    The polymorphic interface established by an abstract parent class suffers from one major limitation
    in that only derived types support the members defined by the abstract parent. However, in
    larger software systems, it is very common to develop multiple class hierarchies that have no common
    parent beyond System.Object. Given that abstract members in an abstract base class only

    apply to derived types, we have no way to configure types in different hierarchies to support the
    same polymorphic interface. By way of an illustrative example, assume you have defined the following
    abstract class:

    abstract class CloneableType
    {
    // Only derived types can support this
    // "polymorphic interface." Classes in other
    // heirarchies have no access to this abstract
    // member.
    public abstract object Clone();
    }
    


    Given this definition, only members that extend CloneableType are able to support the Clone()
    method. If you create a new collection of classes that do not extend this base class, you are unable
    to gain this polymorphic interface. As you would guess, interface types come to the rescue. Once an
    interface has been defined, it can be implemented by any type, in any hierarchy, within any namespaces
    or any assembly (written in any .NET programming language). Given this, interfaces are
    highly polymorphic. Consider the standard .NET interface named ICloneable defined in the System
    namespace. This interface defines a single method named Clone():
    public interface ICloneable
    {
    object Clone();
    }
    If you were to examine the .NET Framework 3.5 SDK documentation, you would find that a
    large number of seemingly unrelated types (System.Array, System.Data.SqlClient.SqlConnection,
    System.OperatingSystem, System.String, etc.) all implement this interface. Although these types
    have no common parent (other than System.Object), we can treat them polymorphically via the
    ICloneable interface type.
    For example, if we had a method named CloneMe() that took an ICloneable interface parameter,
    we could pass this method any object that implements said interface. Consider the following
    simple Program class defined within a Console Application named ICloneableExample:

    class Program
    {
    static void Main(string[] args)
    {
    Console.WriteLine("***** A First Look at Interfaces *****\n");
    // All of these types support the ICloneable interface.
    string myStr = "Hello";
    OperatingSystem unixOS = new OperatingSystem(PlatformID.Unix, new Version());
    System.Data.SqlClient.SqlConnection sqlCnn =
    new System.Data.SqlClient.SqlConnection();
    // Therefore, they can all be passed into a method taking ICloneable.
    CloneMe(myStr);
    CloneMe(unixOS);
    CloneMe(sqlCnn);
    Console.ReadLine();
    }
    private static void CloneMe(ICloneable c)
    {
    // Clone whatever we get and print out the name.
    object theClone = c.Clone();
    Console.WriteLine("Your clone is a: {0}",
    theClone.GetType().Name);
    }
    }
    
     When you run this application, you will find the full name of each class print out to the console,
    via the GetType()method you inherit from System.Object


    VS.Net adventurer ----------------- If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Saturday, November 13, 2010 7:06 PM
  • Pro C# 2010 and the .net 4 Platform

    Quite a good book.

    Bit naughty omiting any mention of what you're quoting from.

    Monday, November 15, 2010 8:18 AM
  • ;)

    Yes, AGAIN, this isn't a discussion about "what is an interface", or "what is an abstract", but rather would the gain of multiple inheritance be worth the added complexity over using interfaces?

     


    http://pdkm.spaces.live.com/
    Monday, November 15, 2010 9:12 AM
  • I think it probably is if your objects' hierarchy and the methods you want are in the right sort of pattern.

    In a Win CE app I've been working on, all screens need 4 pieces of functionality added.  So I have a baseform and all the screenss inherit from it.  There is one exceptional form which needs an extra bit of functionality to turn off the SIP - that's just straight in it's form load rather than adding an extra interface to no gain.

    That's an easy call where adding an interface and then implementing it would just mean I was wasting my time.

    Maybe there's some sort of definition or ruleset that you could apply to decide which approach is best.  I can't think of how to put it in anything but pretty loose terms though.   So loose I would think it'd be of academic interest only.  Maybe that's why someone hasn't come up with one.

    Monday, November 15, 2010 10:01 AM