0

I'm starting to think I don't understand polymorphism quite like I thought I did.

I have the following situation:

public class Testing {
    public static void main(String[] args){
        interTest myTest = new classTest();
        myTest.classMethod();

    }
}

With the given interface:

public interface interTest {

    public boolean checkBoolean();
    public void method();

}

And then the concrete class:

public class classTest implements interTest{

    public classTest() {
        // TODO Auto-generated constructor stub
    }

    public void classMethod(){
        System.out.println("fail");
    }

    // Both method() and checkBoolean() are overridden here & do nothing.

    }

}

The Oracle documents demonstrate implementing an interface and then adding additional methods, or even implementing multiple interfaces (and therefore including methods that aren't in one of the interfaces) and I thought this was commonplace, until I ran into issues trying to do this myself.

In this instance I am not able to access classMethod because it is not inside the interface.

The method classMethod() is undefined for the type interTest

What am I not understanding about polymorphism? I thought declaring a variable in the form:

Interface object = new ConcreteClass();

created an interface object that could access ConcreteClass() methods. This is how you make multiple objects that are all of the same type (interface) and can fit in a type specific list but are different.

Why can't I call the myTest.classMethod() method?

leigero
  • 3,233
  • 12
  • 42
  • 63

1 Answers1

5

At compile time, methods are resolve based on the type of the expression they are invoked on.

In

Interface object = new ConcreteClass();
object.classMethod();

the method classMethod() is invoked on a variable of type Interface which doesn't declare or have a visible method named classMethod().

The type ConcreteClass does declare such a method, so you could do

ConcreteClass object = new ConcreteClass();
object.classMethod();

or even

((ConcreteClass) object).classMethod();

if you were certain object was referencing a ConcreteClass object. Otherwise you would get a ClassCastException at run time.


Basically, you need to learn the difference between compile time type and static type versus run time type and dynamic type.

In

Interface object = new ConcreteClass();

the static type of object is Interface. At run time, the variable is referencing an object of type ConcreteClass, so its run time type is ConcreteClass.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • So when/why would you do something like `List myList = new ArrayList()`? Is there a better way to accomplish this? IE via an abstract class and extensions? – leigero Mar 09 '14 at 05:51
  • 1
    @leigero Go through this question: [What does it mean to "program to an interface"?](http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface) If you want to invoke a method, you need to invoke it on an expression that resolves to a type that declares such a method. How you do that depends on your use case. – Sotirios Delimanolis Mar 09 '14 at 05:52
  • Okay, thanks. Good to know this wasn't quite as obvious as I thought it was (at least not to me). – leigero Mar 09 '14 at 05:53