Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement common behaviour in alternative to abstract base classes?

In C#, I have a class hierarchy with a couple of abstract base classes near the top and a fair number of derived classes. A few these concrete classes have some common properties and methods that are implemented identically. It strikes me as wasteful and so one solution might be to implement this common behaviour in another abstract base class.

abstract class Control;

abstract class SquareControl: Control
{
    public int SquarishProperty;
    public void SquarishMethod();
};

class Window: SquareControl;
class Button: SquareControl;

However, what if several other classes in the hierarchy shared some other behaviour but also share something in common with one of the controls from another base class? Perhaps there are lots of areas of commonality. It would become impractical to model this with abstract base class implementation wouldn't it?

abstract class FlashableControl: Control
{
    public int FlashyProperty;
    public void FlashMethod();
};

class StatusBar: FlashableControl;  // but it's also a bit square too, hmm...

So how do you go about sharing such implementations across classes without using base classes?

I imagine I want to delegate the implementaion of an interface to another class and have that class implement those properties and methods on behalf of the desired classes, so that to the user, the StatusBar and Window appear to support a standard interface, but under the covers it's something else that implements it.

I can visualise aggregating classes that implement this behaviour, but is this appropriate and are there any pitfalls? What are the alternatives?

Thanks

like image 275
DaBozUK Avatar asked Jun 18 '10 21:06

DaBozUK


People also ask

What is a Behaviour of an abstract class?

And one of the best ways I've found to what think about abstract classes in object-oriented programming is to think of them like this: Abstract classes are a substitute for implementation. Perhaps another way to think of them are as placeholders. Ultimately, they provide the behavior that the subclasses must implement.

Can you implement methods in abstract class?

Abstract class in Java is similar to interface except that it can contain default method implementation. An abstract class can have an abstract method without body and it can have methods with implementation also.

Can you inherit behavior from an abstract class?

NO. Abstract methods(defintion) are overridden by base class' overriding methods.

Can you substitute the abstract class with interface concept?

Interfaces can only hold abstract method, also interfaces can implement multiple interfaces to any class. But an abstract hold abstract and non abstract methods, and abstract methods cannot extend to more then one class.


1 Answers

You can use a pattern like this:

public interface ICommonServices
{
    string SomeProperty { get; set; }

    void SomeMethod(string param);
}

public static class CommonServiceMethods
{
    public static void DoSomething(this ICommonServices services, string param)
    {
        services.SomeMethod(services.SomeProperty + ": " + param + " something extra!");
    }
}

All classes that implement ICommonServices now also get some free behavior via the extension method, which depends solely on those features exposed by all ICommonServices implementers. If you need access to base class functionality, you can put that in its own interface and have ICommonServices implement that interface as well. Now you can create 'default' extension functionality for interfaces without having to use multiple base classes.


EDIT

If you want some of these methods to be internal, you can modify the pattern like this:

public class MyObject : IServices
{
    public string PublicProperty { get; private set; }

    string IServices.SomeProperty { get; set; }

    void IServices.SomeMethod(string param)
    {
        //Do something...
    }
}

public interface IPublicServices
{
    string PublicProperty { get; }
}

internal interface IServices : IPublicServices
{
    string SomeProperty { get; set; }

    void SomeMethod(string param);
}

internal static class ServiceMethods
{
    public static void DoSomething(this IServices services, string param)
    {
        services.SomeMethod(services.SomeProperty + ": " + param + " something extra!");
    }
}

Basically we're exposing both public and internal interfaces. Note that we implement the internal interface methods explicitly, so that the methods are not available for public consumption (since the public client can't get access to the interface type.) In this case, the helper extension methods are internal, relying on the internal interface, though you could also create public helper methods that rely on the public interface.

like image 63
Dan Bryant Avatar answered Oct 27 '22 02:10

Dan Bryant