Готовлюсь к экзамену и столкнулся со следующей проблемой:
IntfX — это интерфейс в пакете A, содержащий метод public void op_a(Double e).
CISY — это класс в пакете A, который реализует IntfX и переопределяет op_a.
В пакете B основной класс импортирует пакет A, расширяет CIsY и приступает к перегрузке op_a как public void op_a(Double e, Double f).
Теперь в блоке psvm есть два экземпляра: Intfx a = new Main() и Main b = new Main().
Затем он вызывает a.op_a(Double e, Double f) и c.op_a(Double e, Double f)
Вызов a.op_a завершается неудачно. Показывает ошибку времени компиляции: «ожидаю 1 аргумент, но найдено 2».
Мой вопрос: почему объект a не может использовать перегруженный метод op_a с двумя аргументами? В других задачах, когда есть две версии метода, JVM отдает предпочтение объекту, а не типу.
Код:
`пакет А:
public interface IntfX {
public void op_a(Double a);
public void op_b(Double b);
}
public class CIsY implements IntfX {
protected double v = 0.0;
String p = null;
public CIsY(Double x, String b) {
v = x;
p = b;
}
public void op_a(Double a) {
v += a;
}
public void op_b(Double b) {
v -= b;
}
public void op_c() {
v = 0.0;
p = null;
}
}
Пакет Б:
import pack_a.*;
public class Main extends CIsY{
public static void main(String[] args) {
IntfX a = new Main();
CIsY b = new Main();
Men c = new Main();
c.op_a(0.5,0.8);
a.op_a(0.0, 0.1);
}
public Main() {
super(0.0, "");
}
public void op_a(Double e, Double f) {
v = e + f;
}
public void op_b(Double e, Double f) {
v = e + f;
}
public void op_K(Double d) {
v = d;
}
}
Я ожидал, что a.op_a сможет распознать перегруженный метод и скомпилировать его.
Если я напишу IntfX a = random() ? new Main() : new CIsY();
, то какой метод a.op_a(0.0, 0.1);
вызывает?
Я уверен, что есть дубликат (даже много), которого я еще не нашел, но... Тип переменной a
— IntfX
, и у этого типа нет этого метода. Это действительно так просто. Любой конкретный тип реализации, который присваивается этой переменной, может иметь этот метод, а может и не иметь его, или может иметь любые другие методы. Это не имеет значения. Компилятор может гарантировать, что a
имеет методы для IntfX
, только потому, что этот тип используется для этой переменной.
Возможный дубликат stackoverflow.com/questions/53261487/…
Мне потребовалось некоторое время, чтобы понять, что означает «блок psvm». Просто назовите основной метод.
Потому что цель интерфейса — обеспечить реализацию указанных методов, а в классе Main этого не было сделано.
В вашем примере ваш интерфейс IntfX явно указывает:
https://docs.oracle.com/javase/tutorial/java/concepts/interface.html
Java допускает перегрузку методов. Проще говоря, это означает, что каждый метод, реализованный внутри объекта, должен быть уникальным по крайней мере в одном из двух способов:
Это означает, что когда вы «перегружаете метод», вы на самом деле просто создаете новый отдельный метод, который имеет то же имя. Просто компилятор Java достаточно умен, чтобы распознать, что это разные методы. ОПРЕДЕЛИТЕ методы, имеющие одно и то же имя.
https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
Кстати, проблема в вопросе не ограничивается интерфейсами (и перегруженными методами) - аналогичное поведение ожидается и с классами (Object i = new Integer(123); int value = i.intValue();
не будет компилироваться)
какой тип
a
? (какой тип объекта гарантированно сохраняется)