Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding new method in Java Interface so it involves minimal changes to inheriting classes [duplicate]

Possible Duplicate:
Adding Extra method to interface

There is scenario where I have Interface X, which has been implemented with my thousands of classes. Now I want to add new method in that Interface X. So how to make the changes in minimal way to solve the problem of overridden of methods in all my classes

like image 606
Sougata Bhattacharya Avatar asked Jun 17 '12 05:06

Sougata Bhattacharya


2 Answers

I would create an extension of your interface for only the classes that need the additional methods...

public interface BaseInterface {
    public int exampleMethod();
}

public interface ExtendedInterface extends BaseInterface {
    public int anotherMethod();
}

The thousands of classes already implement BaseInterface. For the classes that need the extra method, you change them to implement ExtendedInterface.

If your objects are stored in a collection such as a BaseInterface[] array, this still works because objects of type ExtendedInterface are also objects of type BaseInterface, so they can still be stored in the same common collection.

For example, this is still perfectly valid...

BaseInterface[] objects = new BaseInterface[2];
objects[0] = new ClassThatImplementsBaseInterface();
objects[1] = new ClassThatImplementsExtendedInterface();

However, if you need to access the new method of the ExtendedInterface, but the object is stored in a BaseInterface collection, you'll need to cast it into an ExtendedInterface before you can use it...

BaseInterface[] objects = new BaseInterface[1];
objects[0] = new ClassThatImplementsExtendedInterface();

if (objects[0] instanceof ExtendedInterface){
    // it is an ExtendedInterface, so we can call the method after we cast it
    ((ExtendedInterface)objects[0]).anotherMethod();
}
else {
    // it is a BaseInterface, and not an ExtendedInterface
}

This may or may not be suitable, depending on your usage.

If you really need all your thousands of objects to implement the new method, you'll have to add the method to the BaseInterface and then use a feature of your IDE or text editor to implement the method in all your classes. For example, you could open them all in a text editor and do a find-replace to find something thats common to each class, and replace it with the common code + the default code for the new method. Pretty quick and painless. I'm sure that some IDEs would probably also automatically add the method declaration to all inheriting classes, or at least have an option to do this in a right-click menu.

like image 64
wattostudios Avatar answered Nov 16 '22 04:11

wattostudios


If the new method is a true extension of the interface, then the right thing to do is edit the interface and use your development environment's tools to find all the places where the new functionality must be implemented. Then do the work. Eclipse and Netbeans will do a fine job.

[NB I'm a bit surprised that refactoring tools don't take care of some of the manual effort, but so it is.]

If the new method won't be called most of the time in old code, consider the new interface to be an extension of the old one:

public interface NewInterface extends OldInterface {
    void newMethod();
}

If you have needs to pass old interface objects to new interface consumers with a null version of newMethod(), you can do something like:

public class NewInterfaceWrapper<T extends OldInterface> implements NewInterface {

    private T wrapped;

    public NewInterfaceWrapper(T wrapped) {
        this.wrapped = wrapped;
    }

    // Define all the old interface methods and delegate to wrapped.method 

    // Now provide the null implementation of new method.
    void newMethod() { }
}

...

wantsNewInterface(new NewInterfaceWrapper(oldImplementer));

It's not pretty, but big systems usually grow rough edges like this as they age.

like image 42
Gene Avatar answered Nov 16 '22 02:11

Gene