Правильно использовать ключевое слово по умолчанию в интерфейсе - PullRequest
3 голосов
/ 11 марта 2020

У меня есть сотрудник, которому нужен метод, который будет доступен для двух классов.

Он решил создать новый интерфейс для реализации этими классами.

В интерфейсе есть один метод default doThis(String parameter)

У него нет других методов интерфейса, нет указаний на то, что в этот интерфейс будут добавлены другие методы.

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

Есть ли у кого-нибудь опыт в этом вопросе, которым можно поделиться?

Я могу обновить с дополнительными разъяснениями, основываясь на ваших комментариях.

Обновление:

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

Интерфейс:

public interface LogInCookie {

    default void mapCookiesToPreferences(String cookie) {
        if (cookie.contains(MiscConstants.HEADER_KEY_REFRESH)) {
            String refreshToken = cookie.replace(MiscConstants.HEADER_KEY_REFRESH, StringUtils.EMPTY);
            SharedPrefUtils.addPreference(SharedPrefConstants.REFRESH_TOKEN, refreshToken);
        } 
    }
}
public class HDAccountActivity extends AbstractActivity implements LogInCookie {

    private void mapCookies(List<String> mValue) {
       LogInCookie.super.mapCookiesToPreferences(mValue); //ekh!
    }

}
public class BaseSplashPage extends AppCompatActivity implements DialogClickedCallBack, LogInCookie {

//method which uses this
private void mapCookiesToPreferences(List<String> headers) {
        int firstItemInHeader = 0;
        for (String header : headers) {
            String  mValue =  header.substring(firstItemInHeader,header.indexOf(MiscConstants.SEMICOLON));
            LogInCookie.super.mapCookiesToPreferences(mValue);  //ekh!
        }
    }

}

Ответы [ 4 ]

5 голосов
/ 11 марта 2020

Метод default в интерфейсе, который не определяет другие методы, не может делать много полезных вещей с экземпляром реализующего класса. Он может использовать только методы, унаследованные от java.lang.Object, которые вряд ли несут семантику, связанную с интерфейсом.

Если код вообще не использует методы экземпляра для this, другими словами, полностью независимо от экземпляра this, вы должны сделать его static, изменить содержащий класс на неинстанцируемый тип class, т.е.

final class SomeUtilClass {
    static void doThis(String parameter) {
    // ...
    }

    private SomeUtilClass() {} //no instances
}

и использовать import static packageof.SomeUtilClass.doThis; в классах, использующих это method.

Таким образом, все эти классы могут вызывать метод, такой как doThis(…) без квалифицирующего имени типа, без необходимости вводить в заблуждение иерархию типов.

Когда метод фактически использует this Экземпляр, который, как сказано, может быть только в терминах методов, унаследованных от java.lang.Object, наследование типов может быть оправданным. Поскольку это маловероятно, вы все равно можете считать, что иерархия типов вводит в заблуждение, и переписать код в

final class SomeUtilClass {
    static void doThis(Object firstParameter, String parameter) {
    // ...
    }

    private SomeUtilClass() {} //no instances
}

, используя firstParameter вместо this, который может быть вызван как doThis(this, …).

1 голос
/ 11 марта 2020

В идеале вы должны поместить этот метод doThis() в абстрактный класс, который расширяет оба класса. Однако, если вам нужно добиться множественного наследования, тогда использование интерфейса здесь хорошо.

Класс со стати c методом doThis(), который вы можете вызывать статически, также будет работать.

Все зависит от того, как вы организовали свой проект imo.

1 голос
/ 11 марта 2020

В java 8 ключевое слово по умолчанию в интерфейсе было введено для тех случаев, когда, если какой-либо набор apis имел длинную иерархию наследования, и мы хотели ввести метод, который должен быть доступен во всех нижележащих классах.

Так, например, в Java 8 метод stream () был представлен в интерфейсе Collection как метод по умолчанию, и в конечном итоге он стал доступен во всех базовых классах.

Насколько ваш случай рассмотрен, если I go По вашим словам, если у вас новая разработка, вы должны использовать интерфейс -> абстрактный класс -> фактический реализующий класс.

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

0 голосов
/ 11 марта 2020

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...