Реализация интерфейса Java - автоматический инициализатор - PullRequest
0 голосов
/ 05 июня 2019

Мне интересно, можно ли заставить какую-либо реализацию определенного интерфейса автоматически выполнять определенное действие во время инициализации самого интерфейса. Примерно так:

public interface MyInterface {

    public static final ArrayList<MyInterface> IMPLEMENTATIONS = new ArrayList<>();

    public static void init(){
        // Somecode...
    }

    void method1();

    void method2();

}

Мне бы хотелось, чтобы при инициализации интерфейса, например, если вызывается метод init , тогда необходимо создать новый экземпляр каждого класса, который реализует интерфейс, и добавить его в ArrayList.

Целью создания чего-то подобного является создание единой программы, которая может запускать любую другую программу, которую я пишу и хочу получить доступной. По сути, он запускается при запуске компьютера и может использоваться для запуска любой другой программы, которую я написал, вместо того, чтобы добавлять каждую новую программу в системную папку автозапуска.

Возможно ли что-то подобное?

Ответы [ 3 ]

1 голос
/ 05 июня 2019

Вместо использования Interface используйте abstract класс. Кроме того, внутри этого класса создайте конструктор с одним аргументом, который принимает ваш абстрактный класс в качестве параметра. И затем в конструкторе вы можете добавить этот параметр в ваш ArrayList.

Затем внутри основного класса вы можете использовать org.reflections для создания экземпляров всех классов, расширяющих ваш класс abstract. А затем вызовите метод init, где вы можете выполнять операции со списком.

public class MyClass{
  private static final List<MyClass> IMPLEMENTATIONS = new ArrayList<>();
  public MyClass(MyClass myClass){
    IMPLEMENTATIONS.add(myClass);
  }
  public static void init(){
    // Do something with IMPLEMENTATIONS
  }
  abstract void method1();

  abstract void method2();

}

package com.mypackage; 
public class Child extends MyClass{
  public Child(){
    super(this);
  }
  // Implement other abstract methods
}

public class MyMainClass{
  public static void main(String[] args) throws IllegalAccessException, InstantiationException { 
    Reflections reflections = new Reflections("com.mypackage"); 
    Set<Class<? extends MyClass>> classes = reflections.getSubTypesOf(MyClass.class); 
    for (Class<? extends MyClass> aClass : classes){ 
      aClass.newInstance(); 
      }
    MyClass.init();
    }
}
0 голосов
/ 05 июня 2019

Ваш вопрос слишком общий, чтобы дать конкретный ответ.Тем не менее (если я вас правильно понял) я написал библиотеку с открытым исходным кодом MgntUtils, которая содержит небольшую платформу с функцией, называемой Self-population factory.В двух словах, вот как это работает: вы можете расширить фреймворк, предоставляемый Factory, и написать свой собственный интерфейс, который расширит интерфейс, предоставляемый фреймворком.Затем вы пишете несколько классов, реализующих ваш интерфейс, и как только конструкторы для ваших классов вызываются, каждый класс вставляет себя в фабрику, поэтому, как только ваша программа запускается (если, например, Spring Boot или Spring Framework) инициирует ваши классы, ваша фабрика полностьюинициализирован и готов к использованию.Во всяком случае здесь соответствующие ссылки на библиотеку и статьи, которые объясняют идею и использование:

Статья, которая объясняет идею более подробно
статья о библиотеке MgntUtils
Описание пакета в javadoc, которое подробно объясняет, как использовать функцию
Полный Javadoc
Github с библиотекой, включающей источники и javadoc
Maven Central со всеми версиями библиотеки

0 голосов
/ 05 июня 2019

В дополнение к ответу Маниша, если вы уже унаследованы от класса;вы могли бы использовать внешний метод, который бы инициализировал экземпляры, наследуемые от вашего интерфейса, через полиморфизм.

Это могло бы дать что-то вроде этих строк:Массив в конструкторе каждого реализующего класса.

...