Как получить доступ к супер-супер-классу в 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
.
Итак, короче говоря, просто не делайте этого.