Вызов переопределенной функции базового класса из метода базового класса - PullRequest
34 голосов
/ 29 января 2011
public class A {
    public void f1(String str) {
        System.out.println("A.f1(String)");
        this.f1(1, str);
    }

    public void f1(int i, String str) {
        System.out.println("A.f1(int, String)");
    }
}



public class B extends A {
    @Override
    public void f1(String str) {
        System.out.println("B.f1(String)");
        super.f1(str);
    }

    @Override
    public void f1(int i, String str) {
        System.out.println("B.f1(int, String)");
        super.f1(i, str);
    }
}


public class Main {
    public static void main(String[] args) {
        B b = new B();
        b.f1("Hello");
    }
}

Я ищу, чтобы этот код вывел:

B.f1(String)
A.f1(String)
A.f1(int, String)

Все же я получаю:

B.f1(String)
A.f1(String)
B.f1(int, String)
A.f1(int, String)

Я понимаю, что в контексте B "this" в A.f1 (String) является экземпляром B. У меня есть возможность сделать цепочку новых B1 (). F1 (String) -> (A's) f1 (String) -> (A's) f1 (int, String)?

Это теоретический вопрос, практически решение, очевидно, было бы в A для реализации закрытой функции, которую вызовут как f1 (String), так и f1 (int, String).

Спасибо,
Максим.

Ответы [ 4 ]

32 голосов
/ 29 января 2011

К сожалению, нет

Как я уверен, что вы знаете, но для полноты излагаю явно - есть только 2 ключевых слова для управления вызовом метода:

  • this - this.method() - ищет метод, начиная с класса вызывающего экземпляра («верхняя» виртуальная таблица экземпляра - подразумеваемое значение по умолчанию)
  • super - super.method() - ищет метод, начиная с родительского класса класса, в котором определен вызывающий метод (виртуальная таблица родителя вызывающего класса - не совсем верно но так проще думать - спасибо @maaartinus)

Я могу представить, что другое ключевое слово (например, текущее?) Делает то, что вы описываете:

  • current - current.method() - ищет метод, начиная с класса, в котором определен вызывающий метод

но у Java такого ключевого слова нет (пока?).

18 голосов
/ 29 января 2011

Боюсь, это невозможно, но есть простой обходной путь:

public class A {
    public void f1(String str) {
        System.out.println("A.f1(String)");
        privateF1(1, str);
    }

    private void privateF1(int i, String str) {
        System.out.println("A.f1(int, String)");
    }

    public void f1(int i, String str) {
        privateF1(i, str);
    }
}
5 голосов
/ 29 января 2011

Переопределенные методы в Java динамически связаны.то есть тип фактического экземпляра объекта диктует, что будет называться.Методы final (которые не могут быть переопределены) и методы private (которые не могут быть унаследованы) статически связаны.

В C ++, для сравнения, вам придется явно создавать функцииvirtual, чтобы получить то же поведение.

0 голосов
/ 13 мая 2015
package main;

public class A {
public void f1(String str) {
    System.out.println("A.f1(String)");
    if (this instanceof B)
        new A().f1(1, str);
    else
        this.f1(1, str);
}

public void f1(int i, String str) {
    System.out.println("A.f1(int, String)");
}

}

class B extends A {
@Override
public void f1(String str) {
    System.out.println("B.f1(String)");
    super.f1(str);
}

@Override
public void f1(int i, String str) {
    System.out.println("B.f1(int, String)");
    super.f1(i, str);
}

public static void main(String[] args) {
A a = new B();
    a.f1("Hello");
}
}
...