Как получить доступ к супер-супер-классу в Java? [Мини-пример внутри]

В приведенном ниже примере, как я могу получить доступ с C к методу method() класса A?

class A {
    public void method() { }
}

class B extends A{
    public void method() { }
}

class C extends B{
    public void method() { }

    void test() {
        method();          // C.method()
        super.method();    // B.method()
        C.super.method();  // B.method()
        B.super.method();  // ERROR <- What I want to know
    }
}

Ошибка, которую я получаю,

Нет экземпляра экземпляра типа B доступный в области

Ответ: Нет, это невозможно. Java не позволяет этого. Подобный вопрос.

Ответ 1

Вы не можете - и очень намеренно. Это нарушит инкапсуляцию. Вы бы пропустили то, что хочет сделать B.method - возможно, проверка аргументов (предполагая, что они есть), принудительные инварианты и т.д.

Как вы могли ожидать, что B будет придерживаться последовательного представления о своем мире, если какой-либо производный класс может просто пропустить любое его поведение?

Если поведение B не подходит для C, оно не должно его распространять. Не пытайтесь злоупотреблять наследованием, как это.

Ответ 2

Следующий код может быть обходным (не приятно, но должен работать):

class A {
    public void method() { }
}

class B extends A {
    public void method() { }
    protected void superMethod() {
         super.method();
    }
}

class C extends B {
    public void method() { }

    void test() {
        method();          // C.method()
        super.method();    // B.method()
        superMethod();     // A.method()
    }
}

Ответ 3

Ну, нет прямого способа сделать это, но вы всегда можете попробовать обходные пути.

Я не уверен в возможности доступа к методу в классе A из класса C, но вы всегда можете получить этот метод.

Вы можете либо создать экземпляр класса A в классе C, и если это выглядит слишком просто, попробуйте использовать API отражения... [текст ссылки] [1]

Extreme Java

Ответ 4

Вы не должны.

Если вы хотите получить доступ к методам в A, от A вместо B.

Когда B extends A, он предполагает, что основной A -объект не будет обрабатываться другими способами, чем то, как он сам это делает. Поэтому, непосредственно обращаясь к методам A, вы можете нарушать функции B.

Предположим, например, что у вас есть класс, который реализует список, MyList. Теперь представьте, что мы расширяем этот список другим классом под названием MyCountingList, который переопределяет методы add() и remove() для подсчета добавляемых/удаляемых элементов. Если вы обойдете метод add() MyCountingList, используя вместо него MyList, вы теперь нарушили функцию подсчета MyCountingList.

Итак, короче говоря, просто не делайте этого.