none
Can I dish out multiple interface implementations from Base as properties to derived classes? RRS feed

  • Question

  • I'm using a base class that inherits from multiple interfaces, however, I'm not sure if what I'm doing is an acceptable practice.

    I have multiple interfaces implemented in this fashion and so far I haven't had a problem. From base I pass implementing classes as properties to derived classes.

    public interface IFirst { void FirstMethod(); } public class First:IFirst { public void FirstMethod() { Console.WriteLine("First"); } } public class BaseClass{ IFirst first = new First()

    Public IFirst bcFirst // this property distributes the interface implementing class to derived classes

    {

    get{return first;}

    }



    NR


    • Edited by Highlander4 Wednesday, January 15, 2020 1:16 AM
    Tuesday, January 14, 2020 4:13 PM

All replies

  • Having a base class implementing multiple interfaces is fine. We do it all the time.

    "From base I pass implementing classes as properties to derived classes."

    This is the part I'm not clear on though as you aren't passing anything in the code you posted. Additionally your base class that you posted doesn't implement any interfaces so it is unclear what you mean by this.

    If you're thinking of an aggregate class where the class is a wrapper around child objects that provide functionality then that is a common pattern. In general the aggregate class accepts the child objects during construction and just exposes them.

    public class SomeType
    {
       public SomeType ( IFirst first, ISecond second, IThird third )
       {
          First = first;
          Second = second;
          Third = third;
       }
    
       public IFirst First { get; }
       public ISecond Second { get; }
       public IThird Third { get; }
    }

    Aggregate classes can simplify code when you have lots of dependencies but often it is a sign of a bigger design issue. If you need to create a wrapper type for lots of dependencies then you're really just hiding the fact you have lots of dependencies. This is a design issue as you either have interfaces that are too granular or too much coupling. Using an aggregate class doesn't change the design, it just hides the details which isn't good. 

    There would be exceptions though if the aggregate provides additional functionality. A good rule of thumb is whether the child object(s) make sense by themselves or only when taking as part of the larger object. An example might be an emulator for a machine. You might have a single class representing the overall machine and child objects for the pieces.

    public class Machine
    {
       public IProcessor Processor { get; }
       public IMemory Memory { get; }
       public IStorage Storage { get; }
    }
     An order and its line items would also be an example, but not fit into the interface concept you mentioned.


    Michael Taylor http://www.michaeltaylorp3.net

    Tuesday, January 14, 2020 5:27 PM
    Moderator
  • Implementing multiple interfaces is supported and common practice. Seems like you can benefit from the new C# 8 feature that allows default interface methods.

    The simplest way of using this feature is by adding a concrete method in an interface, which is a method with a body.

    interface IMyInterface
    {
        void MyMethod() { Debug.Log("IMyInterface.MyMethod()"); }
    }
    The class that implements this interface need not implement its concrete method.
    class MyClass : IMyInterface {} // allowed by the compiler since MyClass implements MyMethod
    
    IMyInterface i = new MyClass();
    i.MyMethod(); // prints "IMyInterface.MyMethod()"


    william xifaras

    Tuesday, January 14, 2020 9:59 PM
  • You need to read it again.  The BaseClass is not implementing any interfaces. It is just instantiating the implementing classes and handing them out as properties to any base derived classes.

    The property in the base class called bcFirst is returning the implementing class First  

    Any class deriving from BaseClass can use First via bcFirst.

    Thanks for the good info though.


    NR

    Wednesday, January 15, 2020 1:15 AM
  • Hi Highlander,

    Thank you for posting here.

    We can certainly do that, and I think that's one of the common uses of inheritance.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, January 15, 2020 2:20 AM
  • Greetings Highlander4.

    In my opinion, interfaces are often over-used. Your sample, for instance, would work just as well without an interface at all.

    public class First { public void FirstMethod() { Console.WriteLine("First"); } } public class BaseClass { First first = new First() Public First bcFirst // this property distributes the implementing class to derived classes { get{return first;} }

    }

    So unless you have multiple classes that need to implement the same interface (AFirst, BFirst, CFirst, and so on) why bother having that interface? I would just use the First concrete class as a property.


    • Edited by Ante Meridian Wednesday, January 15, 2020 4:35 AM tidy up the code a bit
    Wednesday, January 15, 2020 4:32 AM
  • "The BaseClass is not implementing any interfaces. It is just instantiating the implementing classes and handing them out as properties to any base derived classes."

    Why? The purpose of an interface is to abstract away the implementation. Unless there is a good reason, the base class shouldn't be creating them, they should be constructor parameters. If the base type is always going to use a concrete implementation then there is no benefit in using interfaces at all.

    Once you get to the point where these are constructor parameters then you're looking at perhaps IoC. At that point, unless the base class needs these objects as well, then you're just burdening derived types with them. Since constructors are not inherited every derived type would have to either have its own set of constructors to specify these objects or would need to instantiate its own concrete implementation. If a derived type never needs this then it is wasteful.

    Ultimately it boils down to whether the base type needs these objects at all and whether every derived type probably needs them too. If so then it might make sense to have the base type hold them otherwise the derived types can. If you're going to instantiate the types directly then don't bother with the interface at all, just use the type directly. Classes are more flexible than interfaces anyway.


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, January 15, 2020 2:40 PM
    Moderator