Почему метод Java с типом интерфейса не распознает этот перегруженный метод?

Готовлюсь к экзамену и столкнулся со следующей проблемой:

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 сможет распознать перегруженный метод и скомпилировать его.

какой тип a? (какой тип объекта гарантированно сохраняется)

user85421 24.05.2024 21:44

Если я напишу IntfX a = random() ? new Main() : new CIsY();, то какой метод a.op_a(0.0, 0.1); вызывает?

Sebastian Redl 24.05.2024 21:49

Я уверен, что есть дубликат (даже много), которого я еще не нашел, но... Тип переменной aIntfX, и у этого типа нет этого метода. Это действительно так просто. Любой конкретный тип реализации, который присваивается этой переменной, может иметь этот метод, а может и не иметь его, или может иметь любые другие методы. Это не имеет значения. Компилятор может гарантировать, что a имеет методы для IntfX, только потому, что этот тип используется для этой переменной.

David 24.05.2024 21:49

Возможный дубликат stackoverflow.com/questions/53261487/…

David Conrad 24.05.2024 23:33

Мне потребовалось некоторое время, чтобы понять, что означает «блок psvm». Просто назовите основной метод.

David Conrad 24.05.2024 23:34
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Потому что цель интерфейса — обеспечить реализацию указанных методов, а в классе Main этого не было сделано.

В вашем примере ваш интерфейс IntfX явно указывает:

  • У вас должно быть два метода: «op_a» и «op_b».
  • Оба метода должны возвращать void.
  • Оба метода должны принимать один аргумент типа Double с именами переменных «a» и «b» соответственно.

https://docs.oracle.com/javase/tutorial/java/concepts/interface.html

Java допускает перегрузку методов. Проще говоря, это означает, что каждый метод, реализованный внутри объекта, должен быть уникальным по крайней мере в одном из двух способов:

  1. Имя метода уникально
  2. Список параметров метода уникален.

Это означает, что когда вы «перегружаете метод», вы на самом деле просто создаете новый отдельный метод, который имеет то же имя. Просто компилятор Java достаточно умен, чтобы распознать, что это разные методы. ОПРЕДЕЛИТЕ методы, имеющие одно и то же имя.

https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html

Кстати, проблема в вопросе не ограничивается интерфейсами (и перегруженными методами) - аналогичное поведение ожидается и с классами (Object i = new Integer(123); int value = i.intValue(); не будет компилироваться)

user85421 25.05.2024 00:38

Другие вопросы по теме