public interface MyInterface {} public class A implements MyInterface{} public class B implements MyInterface{} public class Tester { public static void main(String[] args){ MyInterface a = new A(); MyInterface b = new B(); test(b); // this is wrong } public static void test(A a){ System.out.println("A"); } public static void test(B b){ System.out.println("B"); } }
You are trying to pass an object referenced by MyInterface reference variable to a method defined with an argument with its sub type like test(B b). Compiler complains here because the MyInterface reference variable can reference any object which is a sub type of MyInterface, but not necessarily an object of B.There can be runtime errors if this is allowed in Java. Take an example which will make the concept clearer for you. I have modified your code for class B and added a method.
public class B implements MyInterface { public void onlyBCanInvokeThis() {} }
Now just alter the test(B b) method like below :
public static void test(B b){ b.onlyBCanInvokeThis(); System.out.println("B"); }
This code will blow up at runtime if allowed by compiler:
MyInterface a = new A(); // since a is of type A. invoking onlyBCanInvokeThis() // inside test() method on a will throw exception. test(a);
To prevent this, compiler disallows such method invocation techniques with super class reference.
I'm not sure what are you trying to achieve but it seems like you want to achieve runtime polymorphism. To achieve that you need to declare a method in your MyInterface and implement it in each of the subclass. This way the call to the method will be resolved at run time based on the object type and not on the reference type.
public interface MyInterface { public void test(); } public class A implements MyInterface{ public void test() { System.out.println("A"); } } public class B implements MyInterface{ public void test() { System.out.println("B"); } } public class Tester { public static void main(String[] args){ MyInterface a = new A(); MyInterface b = new B(); b.test(); // calls B's implementation of test() } }