Home > OS >  Implementing an interface with additional parameters in a method
Implementing an interface with additional parameters in a method

Time:09-30

I have a class MyClass that implements the interface IResp.

public interface IResp {
    Response onResp(String a, String b)
            throws Throwable;
}
public class MyClass implements IResp {

    public onResp(String a, String b, String c) throws Throwable {
...
}

I need the additional String c in onResp method of MyClass

Now, I understand that I can achieve this either by adding unimplemented onResp(String a, String b) throws Throwable{...}, or by making MyClass an abstract class.

Since I'm new to Java, I'd like some advice on what's the better approach, please?

Note: I can make changes only to the class and cannot create or modify the interface

CodePudding user response:

You have to implement method with two parameters if you implement interface IResp. But you can also define a second Method with 3 parameters. For example:

    public class MyClass implements IResp {

        public void onResp(String a, String b) throws Throwable {
            onResp(a, b, null);
        }


        public void onResp(String a, String b, String c) throws Throwable {
            // your logic
        }
    }

CodePudding user response:

If you "implement" an interface method, and change the parameter signature (like adding a third String), this no longer is a valid implementation of the interface. You have to have a method like

public Response onResp(String a, String b) {
    // ...
}

in your MyClass.

I need the additional String c in onResp method of MyClass

The interface IResp most probably exists because there are callers of the onResp() method, and they will provide two Strings, not three. If your onResp() code really can't work without getting an additional piece of information (String c), you have a problem.

Your proposals both won't work (if I understand them correctly):

  • If you just add an empty onResp(String a, String b) method, then that method will be called from outside, do nothing and return.
  • If you declare MyClass to be abstract, then you won't be able to create instances of MyClass, and without an instance of this class, nothing will ever get called.

One (theoretical?) possibility is to change the interface method to use three instead of two parameters and to modify all callers of the interface to provide the expected information as a third parameter. But I guess the interface is fixed, and you're not free to do that.

If you can use the very same c value in all onResp() calls, you can provide the additional String c not with every onResp() call, but ahead of time, when you create the MyClass instance, doing new MyClass("abc"), assuming that "abc" is the appropriate value for c. Your class should look like this:

public class MyClass implements IResp {
    private String myConstantC;
    public MyClass(String c) {
        this.myConstantC = c;
    }
    privateResponse onResp(String a, String b, String c) {
        // your code
    }
    @Override
    public Response onResp(String a, String b) {
        return onResp(a, b, myConstantC);
    }
}

If you cannot live with a single constant c value, but have a chance to somehow find out the necessary c value for a given onResp(a, b) call, you can do something like

public class MyClass implements IResp {
    privateResponse onResp(String a, String b, String c) {
        // your code
    }
    private String findTheCValue(String a, String b) {
        // your way to find and return the correct c value
    }
    @Override
    public Response onResp(String a, String b) {
        String c = findTheCValue(a, b);
        return onResp(a, b, c);
    }
}

CodePudding user response:

Did you mean implementing with an empty body? Implementing the method with an empty body could create problems. Let's assume someone created the method in the interface for a reason.

Say a function gets the interface as a parameter. Which method will they call on it? The two parameter version one.

void someWork( IResp resp ) 
{
 resp.onResp("a","b");
}

Now if the object actually passed in to resp is a MyClass with an empty implementation of the function, it does nothing. Is that what you want?

Making the class abstract would be the better choice than creating an empty implementation. It would mean that someone down the line will give the implementation that makes sends for the two parameter version.

If you implement the two parameter version with a sensible body in MyClass and add a three parameter version to MyClass, but you don't add it to the interface then functions such as f1 won't be able to use it.

The takeaway from this is that you will probably want both versions of onResp in the interface.

  • Related