Используйте методы Java в нескольких классах

#java #class #inheritance #multiple-inheritance

#java #класс #наследование #множественное наследование

Вопрос:

Я знаю, что этот вопрос задавался миллион раз, но я не могу найти достойного ответа.

У меня есть куча методов messenger, таких как debug(String) и tell(CommandSender, String) которые я хочу использовать для различных классов. Это звучит просто и легко, но отсутствие поддержки множественного наследования в Java сделало проблему невероятно сложной для классов, которые уже должны расширять что-то еще.

Интерфейсы не будут работать, насколько я могу судить, потому что интерфейсы не позволяют вам фактически реализовать методы, которые вы в них вводите.

Я рассматривал возможность добавления дополнительных аргументов к методу, чтобы заставить их работать из класса статических утилит, но это приводит к тому, что вызовы методов переходят от debug(String) к к MessageUtil.debug(Plugin, String) , что намного более громоздко, чем хотелось бы.

Я рассматривал возможность создания объекта Messenger, который может обрабатывать эти сообщения, чтобы я мог вызывать messenger.debug(String) , что лучше, но я не могу избавиться от ощущения, что должен быть лучший способ debug(String) уединиться.

Любой совет?

РЕДАКТИРОВАТЬ: эти методы, к сожалению, нельзя сделать статическими без добавления дополнительных параметров; поэтому статический импорт не будет работать.

РЕДАКТИРОВАТЬ: вот пример одного из методов, которые я пытаюсь использовать в нескольких классах. Как вы можете видеть по использованию нестатических глобальных переменных, таких как «плагин» и «отладчики», его нельзя сделать статическим.

 protected myPlugin plugin;
private myList<String> debuggers = new myList<String>();

public void debug(String message) {
    if (debuggers.size() == 0)
        return;
    if (debuggers.contains("\console")) {
        plugin.getServer().getConsoleSender().sendMessage(plugin.getColor()   message);
        if (debuggers.size() == 1)
            return;
    }
    for (Player player : plugin.getServer().getOnlinePlayers())
        if (debuggers.contains(player.getName()))
            player.sendMessage(plugin.getColor()   message);
}
  

Вот еще один пример, который отправляет сообщение каждому игроку на сервере и на консоль, используя те же глобальные переменные, что и выше:

 public void broadcast(String message) {
    for (Player player : mCL.getServer().getOnlinePlayers())
        player.sendMessage(plugin.getColor()   message);

    mCL.getServer().getConsoleSender().sendMessage(message);
}
  

РЕДАКТИРОВАТЬ: broadcast() приведенный выше метод на самом деле не является статическим; это была ошибка копирования-вставки. Я изменил его, чтобы отразить это.

Комментарии:

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

2. Как бы вы посоветовали мне изменить его, чтобы избежать множественного наследования? Я не хочу полагаться на множественное наследование (поскольку я не могу его использовать), но я не знаю другого хорошего способа.

3. Предпочитайте композицию наследованию.

4. Вы против статического импорта?

5. Вполне broadcast() может быть импорт-статический как есть. debug() Похоже, что ваш метод имеет довольно много состояний. Передайте MessageUtil экземпляр своим абонентам или используйте синглтон.

Ответ №1:

Учитывая

это заставляет вызовы методов переходить от debug(String) к MessageUtil.debug(Plugin, String), что намного более громоздко, чем хотелось бы.

Предполагая, что ваши методы являются статическими или могут быть сделаны статическими, вы могли бы использовать static import

 import static mypackage.MessageUtil.debug;

//
debug("Hello");
  

Комментарии:

1. Это хорошая идея, но, к сожалению, здесь она не сработает. Я не могу сделать методы статическими, не добавляя все больше и больше параметров. Я использовал статический импорт для других вещей, которые можно было бы сделать статическими, но здесь это не работает.

2. @REALDrummer Пожалуйста, отредактируйте свой вопрос, и что вы имеете в виду под лучшим способом debug(String) уединения ? Что debug(String) делать?

3. @ElliottFrisch OP прокомментировал в комментариях к вопросу функцию этих методов

4. @ElliottFrisch Я редактирую вопрос, чтобы отразить это. debug(String) предназначен для отправки данного сообщения (строки) любому, кто в данный момент находится в «режиме отладки», а не кому-либо еще.

Ответ №2:

Интерфейсы не будут работать, насколько я могу судить, потому что интерфейсы не позволяют вам фактически реализовать методы, которые вы в них вводите.

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

Комментарии:

1. Я видел это, и это было бы именно то, что мне нужно. Однако это плагин, написанный для работы с уже существующей Java-программой, которая, как я полагаю, не поддерживает Java 8. Я проведу дополнительные исследования, чтобы узнать, смогу ли я заставить его работать с Java 8. Если они поддерживают Java 8, то это было бы идеально.

2. @REALDrummer На самом деле это ничем не отличается от решений для статического импорта (если вы не собираетесь их переопределять). Я не понимаю, как это может вам помочь, поскольку вы упоминаете, что используете нестатические глобальные переменные , с которыми интерфейсы и методы по умолчанию вам не помогут. Как упоминалось в комментариях, композиция — лучший способ, или с помощью синглтона.

3. @ggovan С помощью методов по умолчанию я мог бы создать класс со всеми глобальными переменными и статическими методами, которые принимают дополнительные параметры, которые я не хочу использовать постоянно. Затем я могу создать интерфейс с методами по умолчанию, которые используют эти статические методы, но передают глобальные переменные из класса в качестве необходимых дополнительных параметров. Тогда все классы, которые я хочу, могут реализовать этот интерфейс и иметь все методы без дополнительных параметров и без композиции. Это не самое красивое решение, но оно работает.

4. @ggovan О, и это не будет работать со статическим импортом, потому что методы, которые я хочу использовать, не могут быть статическими. Я работаю в интерфейсе плагина с всеобъемлющим API с множеством вещей, которые должны быть постоянными, но могут и не быть. Это все очень сложно и странно, но это означает, что я, к сожалению, не могу сделать эти методы статическими.