views:

178

answers:

6

I have a class that extends a class that I need to overide, but I need to call that class's parent class. since I can't call super since that will execute the direct parent what is the best way to get the parent of my parent class?

I am sure this is a basic question, but its been a while since I have been doing any 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 */ }
}
+5  A: 

You can't because it has been overridden by B. There is no instance of A inside C.

The thing is that you want to call a method of the class A, but from which instance? You have instantiated C, which is a class with a couple of own and inherited methods from B. If B is overriding a method of A, you can't access it from C, because the method itself belongs to C (is not a method of B, it has been inherited and now it's in C)

Possible workarounds:

B does not override myMethod()

C receives an instance of A and saves it as a class property.

myMethod() in A is static and you use A.myMethod() (I don't recommend it)

pakore
Thanks, I see that I am doing it wrong, but thanks for your explanation. Its helping me to understand.
dan.codes
A: 

I think you're asking the wrong question. What is the problem you are trying to solve?

slipset
This should be a comment, not an answer...
Bozhidar Batsov
Correct, but besides that he's right.
Axel
+1  A: 

Besides what pakore answered, you could also chain super.myMethod() calls if that works for you. You will call myMethod() from A from the myMethod() in 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
    ....
  }
}

You will eventually be calling myMethod from A, but indirectly... If that works for you.

dpb
That will work only if you want B.myMethod() to do exactly the same as A.myMethod(), which leads to the following question: why the hell did u override it in the first time? :)
pakore
@pakore: Sorry... to simple of an example. You call super.myMethod when you need to, based on some conditions, flags etc. I changed the example a little bit to make it clearer
dpb
Yeah I supposed you meant what you have updated now. Keep in mind that your solution is not the same as calling A.myMethod() from C, because, B.myMethod() is doing other things that maybe C doesn't want them to be done. C just wants A.myMethod() things to be done, not that AND a couple more. That's why I said that only works if A.myMethod()===B.myMethod(), and when it does, overriding makes no sense :).
pakore
@pakore: I agree with you! That is why I added the "If that works for you" part :D. If the OP is OK with this behavior then it is a solution, else it is not. Either way, he's breaking encapsulation rules here. Luckily he realized he's approaching this the wrong way.
dpb
A: 

You can't call A's method directly. In the few cases that I've hit this, the solution was to add a method in A to expose it's implementation. E.g.

class A
{
   public myMethod() {
        doAMyMethod();
   }

   void doAMyMethod() {
      // what A want's on doMyMethod, but now it's available
      // as a separately identifiable method
   }
}

class C extends B
{
   public void someStuff() {
      this.doAMyMethod();
   }
}

The scheme separates the public interface (doMyMethod) from the implementation (doAMyMethod). Inheritance does depend upon implementation details, and so this isn't strictly so bad, but I would try to avoid it if possible as it creates a tight coupling between the implementation in A and C.

mdma
+3  A: 

What you are asking is bad practice, What you are saying is that C is not a B, but an A. What you need to do is have C inherit from A. Then you can call super.

If not this is the only way...

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;
}
Romain Hippeau
Thanks, I see that I am doing this the wrong way and have to think of a better solution. I probably don't have to access that grand parents method to do what I want.
dan.codes
+8  A: 

You don't: it violates encapsulation.

It's fine to say, "No, I don't want my own behaviour - I want my parent's behaviour" because it's assumed that you'll only do so when it maintains your own state correctly.

However, you can't bypass your parent's behaviour - that would stop it from enforcing its own consistency. If the parent class wants to allow you to call the grandparent method directly, it can expose that via a separate method... but that's up to the parent class.

Jon Skeet
Thanks, I understand. I guess I am probably approaching this the wrong way.
dan.codes