-4

Im working on a project and for ease of use I wanted to be able to create a class extending my "Screen" interface and the screen class then be initialised from my main method like this -

//Screen Interface
public abstract interface Screen {
    public abstract void init();
}

//Screen Implementation
public class Game implements Screen {

    @Override
    public void init() {
        //Do stuff
    }
}

//Main class
public class Main {

    public static void main(String[] args) {
        Screen s = new Screen();
        s.init();
    }
}

But this doesn't work because you cant instantiate an abstract class. I would have tried

Screen.init();

But you cant call a method like this unless its static. How can I do what i'm trying to achieve? If I was not clear enough please ask in the comments don't just flag and I will update my question.

EDIT: I know I can instantiate the Game class but that is not the point of this. I am trying to run the init method in every class implementing the Screen Interface so I dont have to specify each one induvidually.

Hamish
  • 84
  • 6
  • 1
    Also you seem confused between interfaces and abstract classes – Scary Wombat Aug 23 '16 at 23:52
  • 1
    I don't see the point in declaring an interface abstract. It already is, same with the methods. Methods are also public by default. Also, you cannot instantiate abstract classes nor interfaces. – Andrew Li Aug 23 '16 at 23:52
  • Say you were able to do something like `Screen.init();`, what subclass should that initialize? Why? This smells like an [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Please clarify. – Sotirios Delimanolis Aug 23 '16 at 23:56
  • You haven't explained what you're trying to accomplish, you're just showing us code that doesn't work because it's not supposed to. – shmosel Aug 23 '16 at 23:57
  • @SotiriosDelimanolis I was hoping it was possible all sub classes would be run – Hamish Aug 23 '16 at 23:58
  • 1
    There's no way to implicitly access every instance of a class. You would have to keep a collection of instances and call your method on each one in a loop. Or if it's a global initialization procedure, you can make it static and call it once. – shmosel Aug 23 '16 at 23:59
  • 1
    So you want a `static` `init` method implemented in each subtype to be invoked at startup? – Sotirios Delimanolis Aug 24 '16 at 00:01
  • Here's something: http://stackoverflow.com/questions/3560103/how-to-force-a-class-to-be-initialised – Sotirios Delimanolis Aug 24 '16 at 00:02
  • The way the Java class loader works is that it loads each class into memory the first time you refer to it. It looks for each class by name on its classpath. So you need to know the name of a class before you can get the class loader to load it. There's no way to tell the class loader "load all subclasses of `Screen`" because it doesn't know what to look for. You'll need to approach this differently. – Dawood ibn Kareem Aug 24 '16 at 00:07
  • @DavidWallace so I would have to pass an instance of my Game class to my Screen class? – Hamish Aug 24 '16 at 00:08
  • No, not necessarily. If you have an instance of `Game` you can just run it directly. But your program has to know which classes you want to instantiate. – Dawood ibn Kareem Aug 24 '16 at 00:09
  • Contrary to my earlier comment, this question http://stackoverflow.com/q/3222638 does actually have a way of getting all the classes in the classpath, and you could fish through them to find which ones are subclasses of `Screen`. But I _really_ wouldn't recommend approaching this problem that way. – Dawood ibn Kareem Aug 24 '16 at 00:11
  • [This](http://stackoverflow.com/questions/347248/how-can-i-get-a-list-of-all-the-implementations-of-an-interface-programmatically) *might* help you to get all the subtypes and put them into an array, then loop and initialize all of 'em – Andrew Li Aug 24 '16 at 00:14

3 Answers3

2

why not

Game s = new Game ();
s.init ();

or probably if you have an actually use for the Screen interface then

Screen s = new Game ();
s.init ();

Also you seem confused between interfaces and abstract classes.. You are defining an interface. You do not extend interfaces and you can not instantiate an interface

If you want init to be called automatically then I suggest you add it as a static block or call it from you super constructor

Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
1

In your above code replace this line

Screen s = new Screen();

with this line:

Screen s = new Game();

This will work because of dynamic binding/runtime polymorphism feature of OOPs. At runtime the Object implementing this method (init()) is determined.

Amit Mahajan
  • 895
  • 6
  • 34
-1

You need to instantiate Game, not screen.

John Smith
  • 7,243
  • 6
  • 49
  • 61
Sanjeev Dhiman
  • 1,169
  • 1
  • 11
  • 20