0

I want to make a test program that instead of specifying main method explicitly, extends a class/abstract class and overrides a method that gets called by that superclass eg init.

My attempt:

JavaApplication.java

public class JavaApplication {
    public JavaApplication(){
        this.init(null);
    }

    public JavaApplication(String[] args) {
        this.init(args);
    }

    public void init(String[] args) {
        /* override me */
    }

    public static void main(String[] args) {
        new JavaApplication(args);
    }
}

MyApp.java:

public class MyApp extends JavaApplication {
    @Override
    public void init(String[] args) {
        System.out.println("Hello, World!");
    }
}    

The code compiles but my init method is not called(The string does not appear).

What is the proper way of formulating this behavior in Java?

Related Questions:

  1. can-i-access-a-subclass-method-through-a-base-class-typed-reference
  2. calling-a-method-of-subclass-through-reflection
  3. whats-wrong-with-overridable-method-calls-in-constructors
  4. calling-an-overridden-method-from-a-parent-class-ctor
Community
  • 1
  • 1
Dmytro
  • 5,068
  • 4
  • 39
  • 50
  • 2
    That may be because you **don't** use MyApp –  Aug 18 '16 at 20:17
  • I understand that, but I don't understand how to express it so I do use it. – Dmytro Aug 18 '16 at 20:17
  • 1
    There is only one main, and it is the main that gets called(the one defined in JavaApplication). I want that main to call the subclass(MyApp)'s init rather than its' own but it doesn't seem to be doing that. – Dmytro Aug 18 '16 at 20:19
  • 2
    How on earth is JavaApplication supposed to know it should call init on MyApp, that's the real issue.. –  Aug 18 '16 at 20:23
  • I think it's possible by using reflection(Yes it won't be idiomatic java but that's not my intent, my intent is to force this behavior if it is possible). Similar question: http://stackoverflow.com/questions/14801132/calling-a-method-of-subclass-through-reflection. – Dmytro Aug 18 '16 at 20:53
  • Actually now that I read more sources, I am convinced that the way I am trying to do this is impossible. The parent constructor always runs first, and at the time it runs, the child has not been constructed, and therefore even with reflection (and [I tried](http://hastebin.com/hugikefoso.coffee)) it won't be able to reach into the "final object after inheritance chain", but only into the currently constructed object). – Dmytro Aug 18 '16 at 21:13

1 Answers1

0

You need to add a main method in MyApp that creates an instance of MyApp:

public static void main(String[] args) {
    new MyApp(args);
}

Then, run MyApp instead of JavaApplication.

mapeters
  • 1,067
  • 7
  • 11
  • That ruins the purpose of the experiment. My goal is to have the superclass call the subclass's init. – Dmytro Aug 18 '16 at 20:20
  • @Dmitry - Note that's going to have problems anyway - `MyApp` isn't initialised yet (its constructor hasn't been run), so calling overriden methods from the base-class constructor is likely to lead to sadness, in the general case. – Oliver Charlesworth Aug 18 '16 at 20:24
  • 1
    @Dmitry that violates the purpose of inheritance. Say that you had multiple subclasses, how would the superclass know which subclass's `init` to call? – mapeters Aug 18 '16 at 20:25
  • @mook I am not sure that this is the problem. At the time try to invoke the "init", the constructor doesn't even know it has a child, all it knows is that it has a method named "init". It simply has no way to get ANY children(since the constructor needs to finish before the overriding can occur, and the class architecture does not have a "post-constructor" that recursively goes back downwards after the construction is complete(to let parent to do extra stuff after it has been subclassed via callback)). – Dmytro Aug 18 '16 at 21:24
  • @mook Basically, even If I do have many subclasses, it still won't cause any more confusion since the constructor doesn't get notified once the construction is complete to do "post construction backwards", it simply does "pre-construction" and passes it on and that is all, for all it cares, it has no children. – Dmytro Aug 18 '16 at 21:26
  • @Dmitry - The issue is that you aren't constructing a `MyApp` **at all**, unless you explicitly invoke `new MyApp` (or `MyApp.class.newInstance(...)` for the reflection variant). – Oliver Charlesworth Aug 18 '16 at 21:34
  • isn't the default constructor put in? non static methods can't exist without a constructor, it would not compile if this was the case. The issue is that my default constructor is inherited from JavaApplication and calls only its own constructor but not the subclasses – Dmytro Aug 18 '16 at 21:38
  • @Dmitry - But you aren't calling that constructor. – Oliver Charlesworth Aug 18 '16 at 21:45
  • I'm not, but even if I created the constructor and called init from it, the main method would still never reach my init, it would just construct JavaApplication and call it's init, but it would still display nothing. – Dmytro Aug 18 '16 at 21:48
  • @Dmitry - **call**, not **create**. You aren't **calling** the `MyApp` constructor. – Oliver Charlesworth Aug 18 '16 at 21:49
  • I admitted that I'm not, but that's part of the problem, there is no logical scope where it could get called. main can't see it, nor can JavaApplication. It's simply not possible to do what I want to do exactly how I want to do it as it stands. – Dmytro Aug 18 '16 at 21:54
  • @Dmitry what is your end goal? Maybe we can help you reach it a different way. – mapeters Aug 18 '16 at 22:45
  • Trying to force this specific behavior (moving main to another class). I know other ways it can be done, I was interested if there was a clever way to force it this way. – Dmytro Aug 18 '16 at 23:19
  • @Dmitry but why? You have to have some bigger picture in mind that would make this useful. – mapeters Aug 19 '16 at 01:12
  • @mook checking if its possible. It's a question of what I can or cannot express in which ways and being confident in my expressiveness from experience. – Dmytro Aug 19 '16 at 01:29