2

Say that I in Java have 3 classes, wheres the super one has a function named func(), I now make a subclass which overrides this, and a subclass to my subclass, now working on my sub-sub-class how will I call the 'func()' of the sub class, and the superclass?

I tried casting the 'this' "pointer", but Java 'fixes' it at runtime and calls the subsub func().

Edit: Thanks everyone; 'Skeen is back at the drawing board'.

Skeen
  • 4,614
  • 5
  • 41
  • 67
  • 1
    possible duplicate of [calling super super class method](http://stackoverflow.com/questions/3456177/calling-super-super-class-method) – finnw Jan 19 '11 at 01:49
  • possible duplicate of [Why is super.super.method(); not allowed in Java?](http://stackoverflow.com/questions/586363/why-is-super-super-method-not-allowed-in-java) – Itay Moav -Malimovka Apr 10 '13 at 11:30

7 Answers7

5

The best you can do is call super.func() in your subsub class, and have the func() implementation in your subclass also call super.func().

However, ask yourself, if I need knowledge not only of my parents implementation but also my grandparents implementation, do I have a design problem? Quite frankly this is tripping my "Something stinks in the fridge" instinct. You need to re-evaluate why you want to do this.

rfeak
  • 8,124
  • 29
  • 28
  • Right, I know its hackery, but it would just be one little nasty piece, that would have the rest of the design sparking, instead of having all of it being somewhat nasty, but well.. Coming from C++, then I'm somewhat yet again let down by java. - I guess its time for redesigning >.< (which really sucks, because I never though this would be an issue). – Skeen Jan 18 '11 at 17:17
  • 4
    @skeen Just because C++ let you shoot yourself in the foot, doesn't mean that java is 'letting you down' :)P It's just enforcing a basic inheritance model. If inheritance doesn't work for EVERY behavior of the superclass, perhaps you should consider an encapsulation strategy instead. – robert_x44 Jan 18 '11 at 17:21
  • @RD01 Your right, its not that Java is letting me down, it just feels like it sometimes, Java can feel like somewhat restrictive. - Which can be good, however sometimes I wish one could just turn it off, jeez the Java compiler is worse than my own mom :D. - but I'll try to redesign it. – Skeen Jan 18 '11 at 17:24
  • @skeen - For what it's worth, I felt similarly when I switched from C++ to Java about 10 years ago. Now, in hindsight, it's forced me to be a better developer. The lessons I learned apply just as well to any language. – rfeak Jan 18 '11 at 17:28
  • Look, what people here are saying is that a design that works this way isn't very good. It is not really a language deficiency that you cannot do this, but rather c ++ allows you to do many things, a lot of which are not advisable. It gives you the rope, if you chose tohang it's up to you. By trying to avoid behaviour in your super class, you ar really saying this shouldn't be a sub class. Maybe composition would be more appropriate.. – time4tea Jan 18 '11 at 17:44
1

This isn't possible in Java. And btw. there aren't any pointers in Java.

1

I would jump on the "something in this design smells funny" train. Normally, you override a method so that it works properly for that specific subclass. If you have code in your parent class that is shared across multiple subclasses, perhaps that code could be moved to a non-overridden method so that it is readily accessible by all children/granchildren/etc.

Could you perhaps flip your design over and use more of a template method approach? (http://en.wikipedia.org/wiki/Template_method_pattern)

The notion behind Template Method is that you have some algorithm in your parent class and you can fill in the pieces that need to be class specific by polymorphic calls into your subclasses. You don't have a ton of detail in your question, but by the sounds of things, I'd really take a good look at your design and see if it makes sense.

McGlone
  • 3,434
  • 5
  • 26
  • 31
0

You should probably rethink how you are handling your class hierarchy if you need to place a call to a function that is defined two levels up the hierarchy. Consider writing new methods that are implemented by each subclass in a different way.

EboMike
  • 76,846
  • 14
  • 164
  • 167
James
  • 5,355
  • 2
  • 18
  • 30
  • I guess I have to, however never saw it as a major issue, as the calls system is very well documented, and designed, currently converting the code from C++. – Skeen Jan 18 '11 at 17:19
0

This example is the only way to call a "grandparent" super method.

class A{
    public void foo(){ System.out.println("Hi"); }
}

class B extends A{
    public void foo(){ super(); }
}

class C extends B{
    public void foo(){ super(); }
}

This would be a different story if B doesn't override foo().

Another option would be to have a "protected helper" method in the middle class.

class D{
    public void foo(){ System.out.println("Hi"); }
}

class E extends D{
    public void foo(){ System.out.println("Hello"); }
    protected void bar(){ super.foo(); }
}

class F extends E{
    public void foo(){ super.bar(); }
}
Jeremy
  • 22,188
  • 4
  • 68
  • 81
  • This might be the way to go, its sadly just quite ugly, to have the middle class supply a way to call its super class >. – Skeen Jan 18 '11 at 17:18
  • If `B` doesn't need to override `foo()`, then you would be able to get what you want. – Jeremy Jan 18 '11 at 17:21
  • B and C both overwrites it, however C is interrested in B and A's approaches, but B isn't really interrested in the one from A. – Skeen Jan 18 '11 at 17:27
0

You can access the superclass methods from within the subclass itself, e.g.

class A {
   void foo() {...}
}

class B extends A {
   void foo() {...}
   void defaultFoo() { super.foo(); }
}

However, you really shouldn't be exposing overridden methods this way, you should write B.foo() in such a way that works fine for A and B. This is where it is a good idea to use super.foo(); like this:

 class B extends A {
    void foo() { 
      super.foo(); //call superclass implementation first
      ... //do stuff specific to B
    }
 }

Update: In response to your comment on trying to access the implementation 2 levels up, here's a way of doing it.

class A {
   void foo() { 
     defaultFoo(); 
   }
   protected void defaultFoo() { ... }

}

class B extends A {
   void foo() {...}
}

class C extends B {
   void foo() {
     defaultFoo(); 
     ... //do other stuff
   }
}

This is a healthier pattern of coding what you want to do.

biziclop
  • 48,926
  • 12
  • 77
  • 104
0

Why don't you have func() be not inherited (call it funcBase() or whatever) and then add a wrapper func() function that calls it?

class A{
    public void funcBase() {
        // Base implementation
        }
    public void func() {
        funcBase();
    }
}

class B extends A{
    public void func(){ 
         super.func();
 }
}

class C extends B{
    public void foo(){
         super.func();   // Call B's func
         funcBase();     // Call A's func
    }
}

I have no idea what you're trying to do, but it sounds like your class design is not appropriate for what you want, so you may want separate functions in A instead of trying to sneak your way up the ladder.

EboMike
  • 76,846
  • 14
  • 164
  • 167
  • Its a part of a quite complex particlesys. - And I guess what your writing could be done too, its just.. ugly. – Skeen Jan 18 '11 at 17:21
  • To get better help, you'd provide more details on what you're trying to do. – EboMike Jan 18 '11 at 17:24