Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiate Subclasses from Static Methods

I'm think perhaps there is not a way to do this, but I thought it worth asking. I want to do something like the following:

public class Super {
    public static String print() { System.out.println(new Super().getClass().getSimpleName()); }
    public Super() {}
}

public class Subclass extends Super {
    public Subclass() {}

    public void main(String[] args) {
        Super.print();
        Subclass.print();
    }
}

My hope is to get the Super.print() to show "Super" and Subclass.print() to show "Subclass". I don't see how to do this from a static context however. Thanks for the help.

I'm well aware that I can do this without static methods, and that I can pass a class into each method call. I don't want to do that as that requires redefining several static methods on many subclasses.

like image 480
Blacktiger Avatar asked Jan 21 '23 20:01

Blacktiger


1 Answers

You can simply define a separate Subclass.print() method with the desired implementation. Static methods are class scoped, so every subclass can have its own implementation.

public class Subclass {
    public Subclass() {}
    public static String print() {
        System.out.println(Subclass.class.getSimpleName());
    }

    public void main(String[] args) {
        Super.print();
        Subclass.print();
    }
}

Note that your code can be somewhat simplified - Super.class suffices instead of new Super().getClass().

Also note, that static methods are not polymorphic - Super.print() and Subclass.print() will always call the method in the respective class. This is why they are bound to a class, not an object.

If you have a large class hierarchy, you may end up with a lot of duplicated code by implementing a separate static print() in each. Instead, you could define a single non-static method to do the job:

public abstract class Super {
    public final String print() {
        System.out.println(this.getClass().getSimpleName());
    }
    ...
}

Note that this method does not even need to be polymorphic - this.getClass() will always return the actual subclass token.

Note also that I declared Super as abstract - this is (almost always) good practice to follow with base classes.

like image 55
Péter Török Avatar answered Jan 25 '23 22:01

Péter Török