Есть ли способ использовать интерфейс не статично - PullRequest
1 голос
/ 11 марта 2020

Я пытаюсь реализовать расширенные коллекции в качестве интерфейса и метод дальнейшей отправки мне "Non-static method 'of(java.util.Collection<ELEMENT_TYPE>)'" cannot be referenced from a static context"

Я знаю, что в других темах ответили, но все эти ответы не решают мою проблему.

Заранее спасибо.

Компилятор сообщает мне

**

Error:(22, 54) java: non-static method <ELEMENT_TYPE>of(java.util.Collection<ELEMENT_TYPE>) cannot be referenced from a static context

Error:(31, 62) java: non-static method <ELEMENT_TYPE>of(java.util.Collection<ELEMENT_TYPE>) cannot be referenced from a static context

Error:(22, 63) java: cannot find symbol
  symbol:   method map(this::mapper)
  location: interface java.util.Collection

Error:(31, 71) java: cannot find symbol
  symbol:   method toMap((it)->it.s[...]0, 2))
  location: interface java.util.Collection

Error:(40, 64) java: cannot find symbol
  symbol:   method toSet()
  location: interface java.util.Collection

Error:(40, 55) java: non-static method <ELEMENT_TYPE>of(java.util.Collection<ELEMENT_TYPE>) cannot be referenced from a static context
**

Я точно не имею права редактировать тестовый файл

Редактировать:

Я переписываю переключатель на:

static <ELEMENT_TYPE> ExtendedCollection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list)
    {
        ExtendedCollection<ELEMENT_TYPE> c = new Collection<ELEMENT_TYPE>();
        list.forEach(e -> c.add(e));
        return (ExtendedCollection<ELEMENT_TYPE>) c;
    }

, и теперь он почти работает, я не знаю, как создать экземпляр расширенной коллекции, поскольку она интерфейс

Ответы [ 6 ]

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

Попытка расширить коллекцию - это неправильная вещь.

Вы сможете вызывать эти методы только для того, что реализует интерфейс, то есть вы не можете, скажем, повторно использовать существующие, сражаться Проверенные реализации коллекции, такие как java.util.ArrayList.

Просто определите вспомогательные методы stati c и при необходимости передайте коллекцию.

Фактически, это и есть ваш "интерфейс" на самом деле: вы можете определить метод of как:

static  <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list)
{
    Collection<ELEMENT_TYPE> c = new ArrayList<ELEMENT_TYPE>();
    list.forEach(e -> c.add(e));
    return c;
}

Или, проще:

static  <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list)
{
    return new ArrayList<>(list);
}

Или просто встроить этот код напрямую. Это более понятно, что вы на самом деле получаете, это стандартно и более гибко (вы можете получить такую ​​же гибкость, если измените тип параметра на Collection<? extends ELEMENT_TYPE>).

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

Вы вызываете метод non static, of (который вы определяете в вашем ExtendedCollection interface) из контекста static (т.е. не вызываете его в экземпляр из ExtendedCollection).

Если вы используете java 8 или более позднюю версию, вы можете определять static методы для interface с. В этом случае все, что вам нужно сделать, это изменить объявление метода of, удалив модификатор default и добавив static.

Если вы используете pre java 8, то вот почему java имеет классы, такие как Collections, Executors и др. c. Вы можете определить класс utility , который имеет методы static для возврата элементов типов interface.

0 голосов
/ 11 марта 2020
  1. Вы объявили of как не статичный c метод, но пытаетесь получить к нему статический доступ.
    • Решение a: вызовите of в экземпляре.
    • Решение b (предпочтительно): объявите of static (просто замените default <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of... на static <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of...)
  2. см. 1.
  3. toMap не определено для Collection, вероятно, лучшее решение: сделать of return ExtendedCollection (вместо "normal" Collection ;)
  4. и 5. относятся к / будут исправлены на 3. - 6. на 1.

Да, изменение типа возврата на ExtendedCollection не "так просто": здесь по крайней мере вам нужно инициализировать / предоставить одну реализацию, и да, если вы не выбираете базовый класс, который уже предоставляет add, вам придется его реализовать :

static <ELEMENT_TYPE> ExtendedCollection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list)
{
   ExtendedCollection<ELEMENT_TYPE> c = new MyExtendedCollectionImpl<>();
   list.forEach(e -> c.add(e));
   return c;
}

с:

class MyExtendedCollectionImpl<T>
  extends java.util.ArrayList<T> /* e.g. ...  https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html */
  implements ExtendedCollection<T> { 
     // implement/override ExtendedCollection methods, if any
     // done!
} 
0 голосов
/ 11 марта 2020

изменение метода на:

static <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list)
    {
        Collection<ELEMENT_TYPE> c = new ArrayList<ELEMENT_TYPE>();
        list.forEach(e -> c.add(e));
        return c;
    }

ошибки переключаются на: ** Ошибка: (22, 63) java: не удается найти символ символа: расположение метода (this :: mapper) местоположение : interface java .util.Collection

Ошибка: (31, 71) java: не удается найти символ символа: метод toMap ((it) -> it.s [...] 0, 2 )) местоположение: интерфейс java .util.Collection

Ошибка: (40, 64) java: не удается найти символ символа: метод toSet () расположение: интерфейс java .util.Collection

Ошибка: (46, 64) java: не удается найти символ символа: метод toList () расположение: интерфейс java .util.Collection **

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

Проблема здесь в том, что вы пытаетесь использовать нестатический c метод в статическом c контексте. Ваш метод ExtendedCollection#of() не помечен как stati c, но вы пытаетесь использовать его статически. Это означает, что вместо вызова ExtendedCollection.of(list) вам нужно создать экземпляр ExtendedCollection, прежде чем сделать это. (ExtendedCollection collection = new ExtendedCollection();.

Но, поскольку это интерфейс, вам нужно создать экземпляр подкласса. (Хотя я не понимаю, почему нельзя сделать ExtendedCollection классом вместо интерфейса Кажется, он только добавляет методы по умолчанию, а не какие-либо без реализации. Кроме того, как предположил Энди Тернер, вы можете вместо этого сделать класс stati c вспомогательный / служебный класс, где вы передаете коллекцию, а затем преобразуете ее.

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

Сообщение об ошибке означает, что вы используете нестатический c метод of() в статическом c контексте. Stati c контекст - это когда вы используете ClassName.methodName(). Существует два способа решения проблемы:

  1. Создайте экземпляр, у которого есть метод, который вы хотите вызвать. Поскольку вы объявляете метод в интерфейсе, вам нужно сначала создать класс, который реализует интерфейс:

    public class ExtendedList<T> implements ExtendedCollection<T> {
    }
    

    Теперь вы можете создать экземпляр:

    ExtendedCollection<String> c = new ExtendedCollection<>();
    final List<Integer> ints = c.of(list).map(this::mapper);
    
  2. Измените interface на class и объявите метод как stati c:

    static <ELEMENT_TYPE> Collection<ELEMENT_TYPE> of(Collection<ELEMENT_TYPE> list) {
        Collection<ELEMENT_TYPE> c = new ArrayList<ELEMENT_TYPE>();
        list.forEach(e -> c.add(e));
        return c;
    }
    

За то, что вы пытаетесь выполнить sh здесь, объявив методы как stati c, вероятно, имеют больше смысла.

...