22

Referring here

A is a precompiled Java class (I also have the source file) B is a Java class that I am authoring
B extends A.

How can logic be implemented such that A can call the methods that B has.
The following are the conditions:

  • I don't want to touch A(only as a last option though that is if no other solution exists).
  • I don't want to use reflection.

As stated, if needed I could modify A. What could be the possible solution either way?

Community
  • 1
  • 1
Kevin Boyd
  • 12,121
  • 28
  • 86
  • 128

3 Answers3

47

Class A should define the methods it's going to call (probably as abstract ones, and A should be an abstract class, per Paul Haahr's excellent guide); B can (in fact to be concrete MUST, if the method are abstract) override those methods. Now, calls to those methods from other methods in A, when happening in an instance of class B, go to B's overrides.

The overall design pattern is known as Template Method; the methods to be overridden are often called "hook methods", and the method performing the calls, the "organizing method".

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • @ Alex Class A is some sort of library class and its not abstract. To use the library I am extending A. What do I do in this case? – Kevin Boyd Sep 07 '09 at 01:35
  • @unknown, glad you liked it!-) – Alex Martelli Sep 07 '09 at 01:36
  • 1
    @Kevin, if it's a library class then it cannot sensibly know about application-level classes -- that's WAY the wrong direction for a dependency arrow! Look up Dependency Inversion: make an interface (it's perfectly fine to depend on abstract things such as interface) and have your application class implement that, use Dependency Injection to supply the library class instance with the interface implementation it needs to make calls on. BTW, if the library supplies concrete classes and yet requires you to extend them, its design is dubious: send Haahr's essay to the lib's architect(s)!-) – Alex Martelli Sep 07 '09 at 01:39
  • @Alex: I understood the first part that is B implements Interface I, what is Dependency Injection? Doesn't A need to hold a reference of I to call B's methods then? should I insert a field private Inteface I in Class A? – Kevin Boyd Sep 07 '09 at 01:52
  • 2
    Dependency Injection (search for it!) can be implemented in many ways (there are frameworks that automate it, and many manual approaches) but it does boil down to A holding a private reference to an interface I (otherwise, where would it call I'd methods?-). As you're keen on having B (which extends A) implement I (breaking the Design Pattern First Two Principles: program to an interface, not to an implementation; prefer composition to inheritance), either have A take I in its constructor that B call, or a `setTheI` setter (which B's constructor can call with `this` as the argument). – Alex Martelli Sep 07 '09 at 03:01
  • @Alex, except that if B extends A and B is also the implementation of I, then A can't take the I in it's constructor because that would result in super(this), which will be bounced as a reference to this before the invocation of super() is complete; you would need to get ugly with something like a private instance method which returned I, like: private I returnMe() { return this; } – Lawrence Dol Sep 07 '09 at 05:19
  • @Software Monkey, then the `setTheI` setter approach is clearly simpler and sounder (in other languages there's no problem passing a pointer or reference to this/self to super's constructor, so either approach would be fine). – Alex Martelli Sep 07 '09 at 06:32
  • The link of Paul Haahr's guide is dead. Do you know another one? – Michel Mar 02 '16 at 20:51
  • Use the Wayback Machine, @Michel -- https://web.archive.org/web/20080829234446/http://www.webcom.com/~haahr/essays/java-style/structure.html – Alex Martelli Mar 03 '16 at 22:24
  • Ah thank you! Stupid that I didn't think about that myself. – Michel Mar 03 '16 at 22:26
17

Yes it seems that if you override the super/base-classes's functions, calls to those functions in the base class will go to the child/derived class. Seems like a bad design in my opinion, but there you go.

class Base
{
    public void foo()
    {
        doStuff();
    }
    public void doStuff()
    {
        print("base");
    }
}

class Derived extends Base
{
    @Override
    public void doStuff()
    {
        print("derived");
    }
}

new Derived().foo(); // Prints "derived".

Obviously all of Derived's methods have to be already defined in Base, but to do it otherwise (without introspection) would be logically impossible.

Timmmm
  • 88,195
  • 71
  • 364
  • 509
  • 10
    Google has implemented this exact structure in AsyncTask with Base class as abstract. I am unable to understand how its bad design – Diffy Apr 08 '15 at 16:55
  • 1
    I can't remember my exact thoughts but I'd guess I was bemoaning the fact that all methods in Java are virtual by default. In C++ you have to declare that a method can be overridden in a derived class (whereas in Java you have to prevent it explicitly with `final`). Maybe. – Timmmm Apr 14 '15 at 12:19
  • *"Seems like a bad design"* - Seems like sensible default behaviour to me: normally you override a method because you *want* your overriding version to be called. (Not sure if there is a way for the base class to explicitly call its own method instead of any overriding one from a subclass.) – nnnnnn Jun 09 '17 at 07:11
  • This doesn't answer the question. Base -> Parent, Derived -> Child. The question was, "can the Parent class call Child class methods?". You've shown the child class can call parent methods. – nz_21 Dec 02 '18 at 13:49
  • 1
    No I haven't... `Base.foo` clearly calls `Derived.doStuff`. – Timmmm Dec 03 '18 at 10:12
1

I would be rather hesitant to do this. Please correct me if I am wrong and then I will delete, but it sounds like you want to maintain an A object along with a B object. If they indeed are not the same object, the "tying together" (that's a scientific term) you'll have to do would be pretty ugly.

San Jacinto
  • 8,774
  • 5
  • 43
  • 58