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");
}
}
Вы пытаетесь передать объект, на который ссылается ссылочная переменная MyInterface
, методу, определенному с аргументом с его подтипом типа test(B b)
. Компилятор жалуется здесь, потому что ссылочная переменная MyInterface
может ссылаться на любой объект, который является подтипом MyInterface
, но не обязательно объектом B
. Могут быть ошибки времени выполнения, если это разрешено в Java. Возьмите пример, который сделает концепцию более понятной для вас. Я изменил ваш код для класса B
и добавил метод.
public class B implements MyInterface {
public void onlyBCanInvokeThis() {}
}
Теперь просто измените метод test(B b)
, как показано ниже:
public static void test(B b){
b.onlyBCanInvokeThis();
System.out.println("B");
}
Этот код будет взорван во время выполнения, если это разрешено компилятором:
MyInterface a = new A();
// since a is of type A. invoking onlyBCanInvokeThis()
// inside test() method on a will throw exception.
test(a);
Чтобы предотвратить это, компилятор запрещает такие методы вызова методов со ссылкой на суперкласс.
Я не уверен, чего вы пытаетесь достичь, но кажется, что вы хотите достичь полиморфизма во время выполнения. Для этого вам нужно объявить метод в вашем MyInterface
и реализовать его в каждом из подклассов. Таким образом, вызов метода будет разрешен во время выполнения на основе типа объекта, а не ссылочного типа.
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()
}
}