Неожиданное поведение в привязке метода - PullRequest
0 голосов
/ 05 января 2020

В java перегруженные методы связываются с использованием привязки stati c во время компиляции, тогда как переопределенные методы связываются с использованием динамической привязки c во время выполнения. Я пытаюсь понять динамические c и stati c обязательные в этом вопросе.

class A {
    public void foo(Object o) {
        System.out.println("A");
    }
}

class B {
    public void foo(String o) {
        System.out.println("B");
    }
}

class C extends A {
    public void foo(String s) {
        System.out.println("C");
    }
}

class D extends B {
    public void foo(Object o) {
        System.out.println("D");
    }
}

class Test {
    public static void main(String[] args) {
        A a = new C();
        a.foo("Java");
        C c = new C();
        c.foo("Java");
        B b = new D();
        b.foo("Java");
        D d = new D();
        d.foo("Java");
    }
}

Выход:

A
C
B
B

В строке A a = new C() я знаю, что foo - перегруженная функция. Перегруженные функции разрешаются во время компиляции и связываются с использованием привязки stati c. Мы знаем, что для привязки stati c используется тип. У меня вопрос какой тип? Введите тип аргумента вызова функции (a.foo("Java")) или тип класса A? Если тип класса, то, пожалуйста, следуйте за мной ниже.

В строке D d = new D() функция foo снова перегружена. Перегруженные функции связывают stati c переплет и stati c переплет использует тип. Если мы определили тип класса, то он должен напечатать D, но он печатает B. Не могли бы вы объяснить это поведение и мой прежний вопрос?

1 Ответ

0 голосов
/ 05 января 2020

Сигнатура метода определяется типами параметров * stati c. Конкретный метод выбирается динамически во время выполнения посредством динамического связывания c (но он должен соответствовать сигнатуре метода, определенной во время компиляции). Пример:

class Ideone {
    public static void main (String[] args) {
        String s = "bar";
        Object o = s;
        Ideone ideone = new Idetwo();
        ideone.foo(s);
        ideone.foo(o);
    }

    public void foo(String s) {
        System.out.println("Ideone: String");
    }

    public void foo(Object o) {
        System.out.println("Ideone: Object");
    }
}

class Idetwo extends Ideone {
    @Override
    public void foo(Object o) {
        System.out.println("Idetwo: Object");
    }
}

Ideone demo

Переменная s имеет тип c stati String, таким образом foo(String s) называется. Переменная o имеет тип c stati Object, при этом вызывается foo(Object o). В обоих случаях конкретный метод выбирается динамически. Следовательно, когда выполняется ideone.foo(o);, вызывается foo(Object o) из Idetwo вместо foo(Object o) из Ideone.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...