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?

  • Since when can you not extend an interface? In fact a subinterface uses the extends keyword when extending a superinterface in Java. – user22815 Jun 9 '16 at 17:02
  • Snowman: An interface can extend an interface, but a class cannot extend an interface. I could make a ManagerInterface extends Employee but then my Manager implements ManagerInterface would still have to declare an implementation for every method of Employee and of ManagerInterface, leaving me where I started. – Jared K Jun 9 '16 at 17:19
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.

  • if Manager implements Employee, what happens when you accidentally pass an already Manager Employee as a parameter to a new Manager? – uylmz Jun 10 '16 at 23:01
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.