Java: Как вы получаете доступ к методу родительского класса на два уровня?
У меня есть класс, который расширяет класс, который мне нужно переопределить, но мне нужно вызвать этот класс родительского класса. потому что я не могу назвать супер, так как это приведет к непосредственному родительскому объекту, каков наилучший способ получить родительский элемент моего родительского класса?
Я уверен, что это основной вопрос, но это было некоторое время с тех пор, как я делал любую java.
class A
{
public void myMethod()
{ /* ... */ }
}
class B extends A
{
public void myMethod()
{ /* Another code */ }
}
class C extends B
{
I need to call Class A here
{ /* Another code */ }
}
Ответы
Ответ 1
У вас нет: он нарушает инкапсуляцию.
Хорошо сказать: "Нет, я не хочу своего поведения, я хочу, чтобы мое родительское поведение", потому что предполагалось, что вы это сделаете, только когда оно правильно сохранит ваше собственное состояние.
Однако вы не можете обойти поведение своего родителя - это не позволит ему обеспечить свою собственную согласованность. Если родительский класс хочет разрешить вам напрямую вызвать метод grandparent, он может разоблачить это с помощью отдельного метода... но это до родительского класса.
Ответ 2
Вы не можете, потому что он был переопределен B. Нет экземпляра A внутри C.
Дело в том, что вы хотите вызвать метод класса A, но из какого экземпляра? Вы создали экземпляр C, который представляет собой класс с несколькими собственными и унаследованными методами из B. Если B переопределяет метод A, вы не можете получить к нему доступ из C, потому что сам метод принадлежит C (это не метод из B, он был унаследован, а теперь он в C)
Возможные обходные пути:
B не отменяет myMethod()
C получает экземпляр A и сохраняет его как свойство класса.
myMethod()
в статичен, и вы используете A.myMethod()
(я не рекомендую его)
Ответ 3
То, что вы спрашиваете, - это плохая практика. Что вы говорите, так это то, что C не является B, а A. Что вам нужно сделать, это наследовать C от A. Тогда вы можете вызвать super.
Если это не единственный способ...
public String A()
{
String s = "hello";
return s;
}
public String B()
{
String str = super.A();
return str;
}
public String C()
{
String s = super.B();
return s;
}
Ответ 4
Кроме того, что ответил pakore, вы могли бы также вызвать вызовы super.myMethod()
, если это сработает для вас. Вы вызываете myMethod()
из A из myMethod()
в B.
class A {
public void myMethod() {
....
}
}
class B extends A {
public void myMethod() {
....
super.myMethod();
....
}
}
class C extends B {
public void myMethod() {
....
super.myMethod(); //calls B who calls A
....
}
}
В конечном итоге вы будете называть myMethod из A, но косвенно... Если это работает для вас.
Ответ 5
Вы не можете напрямую вызвать метод. В немногих случаях, когда я ударил это, решение заключалось в том, чтобы добавить метод в A, чтобы показать его реализацию. Например.
class A
{
public myMethod() {
doAMyMethod();
}
void doAMyMethod() {
// what A want on doMyMethod, but now it available
// as a separately identifiable method
}
}
class C extends B
{
public void someStuff() {
this.doAMyMethod();
}
}
Схема отделяет открытый интерфейс (doMyMethod) от реализации (doAMyMethod). Наследование зависит от деталей реализации, и поэтому это не так уж плохо, но я постараюсь избежать его, если это возможно, поскольку это создает плотную связь между реализацией в и C.
Ответ 6
Что я делаю для этого случая:
Сделать объект класса А внутри класса C и получить доступ к классу A.
Этот пример поясняет более подробно:
class A{
int a;
}
class B extends A{
int a;
}
class C extends B{
int a;
A obj = new A();
public void setData(int p,int q, int r) {
this.a = p; // points to it own class
super.a = q;// points to one up level class i.e in this case class B
obj.a = r; // obj points the class A
}
public void getData() {
System.out.println("A class a: "+ obj.a);
System.out.println("B class a: "+ super.a);
System.out.println("C class a: "+this.a);
}
}
public class MultiLevelInheritanceSuper {
public static void main(String args[]){
C2 obj = new C2();
obj.setData(10, 20, 30);
obj.getData();
}
}
Результат этого примера:
A class a: 30
B class a: 20
C class a: 10