Если вы на самом деле все еще хотите main
в каждом классе, но при этом SuperFoo
создайте экземпляр подкласса и вызовете bar()
, вы можете сделать это с помощью ссылок на методы и Supplier<SuperFoo>
class SuperFoo {
static void create(Supplier<SuperFoo> supplier) {
SuperFoo foo = supplier.get();
foo.bar();
}
void bar() { ... }
}
class Foo1 extends SuperFoo {
public static void main(String[] args) {
SuperFoo.create( Foo1::new );
}
}
class Foo2 extends SuperFoo {
public static void main(String[] args) {
SuperFoo.create( Foo2::new );
}
}
class Foo3 extends SuperFoo {
public static void main(String[] args) {
SuperFoo.create( Foo3::new );
}
}
Любая общая предварительная инициализация может быть перемещена в метод SuperFoo::create
до вызова поставщика для создания экземпляра подкласса. Например, открытие соединения с базой данных.
И у вас все еще есть отдельные методы подкласса main
для конкретной инициализации экземпляра. Например, Foo1::main
, Foo2::main
и Foo3:main
могут устанавливать (но не открывать) соединения с различными базами данных.
На основании комментария в ответе Эрнеста, в котором содержится ссылка на ваш код комикеттера, и просматривается эта кодовая база ...
Похоже, вы хотите ServiceLoader
interface FooInterface {
String getName();
void bar();
}
abstract class SuperFoo implements FooInterface {
...
}
public class Foo1 extends SuperFoo {
public String getName() { return "Name1"; }
public void bar() { ... }
}
class Main /* extends nothing, implements nothing! */ {
public static void main(String args[]) {
List<String> names = List.of(args);
boolean all = names.size() == 0;
ServiceLoader<FooInterface> loader = ServiceLoader.load(FooInterface.class);
for (FooInterface foo : loader) {
if (all || names.contains(foo.getName()) {
foo.bar();
}
}
}
}
В файле META-INF/services/your.package.name.FooInterface
вам нужны строки:
your.package.name.Foo1
your.package.name.Foo2
your.package.name.Foo3
Вызвать Main::main
с аргументами: имя ( примечание: не имя класса) или имена (во множественном числе) тех Foo, которые вы хотите, или без имени для использования всех Foo.
Обратите внимание, что class Main
не знает Foo1
или Foo2
или Foo3
. Загрузчик службы ищет вещи в пути к классам, которые содержат META-INF/services/your.package.name.FooInterface
. Позже вы можете добавить больше jar-файлов с большим количеством FooInterface
сервисов для вещей, о которых основное приложение не знает (Foo4
, Foo5
, ...), и они автоматически станут поддерживаться приложением.