Подтвердить что ты не робот

Вызов функции переопределения базового класса из метода базового класса

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 instance. У меня есть возможность сделать цепочку new B1(). F1 (String) → (A) f1 (String) → (A) f1 (int, String)?

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

Я боюсь, это невозможно, но есть простой способ:

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);
    }
}

Ответ 3

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

В С++ для контраста вам нужно явно сделать функции virtual для получения того же поведения.

Ответ 4

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");
}
}