Reputation: 4339
I have an abstract class like so:
public abstract class MyAbstractClass {
protected String greeting;
public void run() {
doSomething();
}
public abstract void doSomething();
}
... and a subclass like so:
public class MyClass extends MyAbstractClass {
public MyClass() {
this.greeting = "Hello, World!";
}
public void doSomething() {
System.out.println(greeting);
}
public static void main(String[] args) {
MyAbstractClass c = new MyClass();
c.run();
}
}
I'm going to be creating multiple subclasses, all of them will have the same main method that just instantiates the subclass. Is there a cleaner way of writing this so I don't need to duplicate the main method in every subclass with a different subclass name? So if I create a new subclass called MyOtherClass
I don't need to put a main method in with MyAbstractClass c = new MyOtherClass();
I guess I can do it the other way round, where I run the main from the abstract class and instantiate the subclass in there, but then each time I want to change which subclass is instantiated I'd obviously need to change the class name after new
. I suppose what I'm looking for is a way to define the main method in the abstract class in such a way that when I run the subclass, it instantiates a copy of the subclass and not the abstract class. If that makes sense...
Upvotes: 0
Views: 10134
Reputation: 236004
This seems like a good fit for the factory method pattern. Try something like this:
public abstract class MyAbstractClass {
protected String greeting;
public void run() {
doSomething();
}
public abstract void doSomething();
public abstract MyAbstractClass makeClass();
}
public class MyClass1 extends MyAbstractClass {
public MyClass1() {
this.greeting = "Hello, World!";
}
@Override
public void doSomething() {
System.out.println(greeting);
}
@Override
public MyAbstractClass makeClass() {
return new MyClass1();
}
}
Then, whenever you need to create a specific instance just call makeClass()
in a single implementation of the main()
method located in the place you consider most convenient, for instance in MyAbstractClass
:
MyAbstractClass mac = new MyClass1();
MyAbstractClass obj = mac.makeClass();
The last line will return an appropriate instance depending on the class used for instantiating the concrete object.
Upvotes: 2
Reputation: 691765
This is where dynamic class loading can be useful. If all your subclasses agree to have a no-arg constructor, you can simply use a single Main class with the main method, and pass the class to use as argument:
java com.foo.bar.Main com.foo.bar.MyFrouteenthSubclass
The main method would simply look like this:
public static void main(String[] args) throws Exception {
String className = args[0];
MyAbstractClass object = (MyAbstractClass) Class.forName(className).newInstance();
object.run();
}
You could also assign a name to all your subclasses and store on instance of each of them in a Map<String, MyAbstractClass>
, and simply call the main class with the name of the class as argument:
java com.foo.bar.Main fourteen
Upvotes: 2