Certo. Dato:
codice:public class A { public void test(Object o) { System.out.println("A.test(Object o)"); } public void test(String s) { System.out.println("A.test(String s)"); } } public class B extends A { public void test(Object o) { System.out.println("B.test(Object o)"); } public void test(String s) { System.out.println("B.test(String s)"); } }
e poi es.:
codice:A obj = ........ Object arg = "hello"; obj.test(arg);
Il compilatore sceglie innanzitutto la signature da invocare. Il compilatore non guarda e non "sa" cosa c'è assegnato a obj. Io ho messo dei puntini .... potrei assegnare new A() o new B(), il compilatore non può sapere cosa succederà a runtime, e io potrei assegnare un oggetto A o B in base ad altre condizioni.
Quindi il compilatore si basa solo sul tipo "statico" del reference (della variabile obj) che è A.
Esiste un metodo "test" noto in A che riceve 1 argomento? Sì.
Inoltre il tipo "statico" dell'argomento (variabile arg) è Object. Idem anche qui il compilatore non guarda cosa c'è assegnato a arg (non può saperlo a priori in generale). Il fatto che ho assegnato la stringa fissa "hello" non cambia le cose.
Quindi esiste un metodo "test" in A che riceve un Object? Sì. Stop, per il compilatore finisce qui. La signature da usare è test(Object).
Poi se a runtime viene istanziato e assegnato realmente un oggetto A a obj, allora sarà il suo test(Object) ad essere eseguito (quindi vedi "A.test(Object o)").
Se invece a runtime viene istanziato e assegnato realmente un oggetto B a obj, allora sarà il suo (e non quello di A) test(Object) ad essere eseguito (quindi vedi "B.test(Object o)").
Andrea, andbin.dev – Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
java.util.function Interfaces Cheat Sheet — Java Versions Cheat Sheet