0

Suppose I have an interface Employee and there are many classes that implement it, such as Bob, Joe, and Mary, none of which may be changed.

public interface Employee{
  public void work()
}

public class Mary implements Employee{
  public void work(){
    //Mary's implementation of work
  }
}

I must make a Manager class that is a wrapper for an Employee object. So the constructor for Manager takes an object of type Employee

Public class Manager{
private Employee employee;

  public Manager(Employee employee){
     this.employee = employee;
  }

  public void work(){
    this.employee.work()
  }

  public void manage(){
     //my implementation of manage
  }


}

When a Manager object is instantiated, it should have all the methods of the underlying Employee plus a few extra. Most of the methods of the underlying Employee object will not be overridden (see work), and thus I think I should be extending Employee. But a class cannot extend an interface. Currently, I am working on declaring each of the Employee methods within the Manager class and having them simply call the corresponding Employee method. But that seems like unnecessary boilerplate and like it will break if the Employee interface ever changes.

Since extending an interface is not allowed, What is the correct design pattern for what I am trying to do?

Jared K
  • 103

3 Answers3

2

You don't need inheritance in this case, you need composition:

public interface Manager {
    void manage();
}

public class Mary implements Employee, Manager{
    public void work(){
        //Mary's implementation of work
    }

    public void manage(){
        //manage
    }
}

Java allows classes to implement multiple interfaces, and is a good guideline: Why should I prefer composition over inheritance?

If you literally cannot change the Mary class, than you should do a wrapper object like you have, which would act as an Adapter for the Employee class instances.

I don't think you need to extend the Employee interface, since you did not indicate that it will need a work() method.

0

You said I must make a Manager class that is a wrapper for an Employee object Purpose of the wrapper exactly what you described, it wrap some other behavior under own methods.

I think your Manager class need to implement Employee interface.

Public class Manager implements Employee
{
    private Employee employee;

    public Manager(Employee employee)
    {
        this.employee = employee;
    }

    public void work()
    {
        this.employee.work();
    }

    public void manage()
    {
        //my implementation of manage
    }
}

In this case Manager class wrap behavior of Employee interface and extend it with own manager behavior.

Fabio
  • 3,166
0

The way you're doing it is basically the usual way of doing this in a static language. You should probably declare your Manager to implement Employee, but other than that there really isn't a better way of achieving the result you want.

In some dynamically-typed languages (e.g. Ruby or Smalltalk) there is another alternative: you can implement a method that gets called if your object is sent an unrecognised message (i.e. it's called with a method it doesn't know about), and you can then forward that message to the target object. Java has no way of doing this.

Jules
  • 17,880
  • 2
  • 38
  • 65