Question

I have a class defined by an interface

public interface Test {
    void testMethod();
}

Test test = new TestImpl();

public class TestImpl implements Test {
    @Override
    public void testMethod() {
         //Nothing to do here
    }

    public void anotherMethod() {
        //I am adding this method in the implementation only.
    }
}

How can I call anotherMethod?

test.anotherMethod(); //Does not work.

I want to be able to define a few methods in the implementation only because in my production code, the Test interface covers a pretty broad spectrum of classes and is implemented by multiple classes. I use methods defined in the implementation to set dependencies that aren't covered by the DI framework in my unit testing so the methods change from implementation to implementation.

Was it helpful?

Solution

The problem is with the following line:

Test test = new TestImpl();

This tells the compiler to forget that the new object is a TestImpl and treat it as a plain old Test. As you know, Test does not have anotherMethod().

What you did is called "upcasting" (casting an object to a more general type). As another poster has said, you can fix your problem by not upcasting:

TestImpl test = new TestImpl();

If you're sure that a Test object is really a TestImpl, you can downcast it (tell the compiler it is a more specific type):

Test test = new TestImpl();
:
((TestImpl) test).anotherMethod();

This is generally a bad idea, however, since it can cause ClassCastException. Work with the compiler, not against it.

OTHER TIPS

use

TestImpl test = new TestImpl();

then

test.anotherMethod();//It will work now

I think through your Interface reference it is impossible to call any method which is not defined in that interface.

If you want to avoid casting directly to your implementation class, I would create another interface:

public interface SpecificTest extends Test { 
    void anotherMethod();
}

And then have your TestImpl implement that interface (which means you can declare it as either Test or SpecificTest ):

SpecificTest test = new TestImpl();
test.anotherMethod();

Of course you can access your methods as was answered above, but you should adhere to best practices in programming. So you if you can't add required methods to Interface1 create Interface2 that extends Inteface1 and finally add your methods.

You can call it if you cast to the implementing class, the one that implements that method In short:

Test test = new TestImpl();

// ... and later / somewhere else

((TestImpl) test).anotherMethod();

If you do not want to type cast it to the concrete class then you could make anotherMethod() as private method and call it inside testMethod() based on some logic.

for eg.

testMethod()
{
   if(foo)
  {
     anotherMethod();
  }
}

This is a workaround that you can use if you do not want to create new methods in child class , since you cannot call them using a parent class/interface reference.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top