Несовместимые типы JAVA… «не могут быть преобразованы в»

#java

#java

Вопрос:

При попытке скомпилировать следующий код я получаю сообщение об ошибке:

 [ERROR] /C:/workspace/Oefeningen/3/Opdracht 2/programmeren_ex-adreslijst-java/src/main/java/be/uantwerpen/AdresLijst.java:[39,16] incompatible types: java.util.ArrayList<be.uantwerpen.Adres> cannot be converted to be.uantwerpen.AdresLijst
  

Я не уверен, что именно это означает и, следовательно, как это исправить.
Любая помощь будет оценена.

Пожалуйста, игнорируйте голландские имена, они не важны.

 package be.uantwerpen;

import java.util.ArrayList;

public class AdresLijst implements AdresLijstIf {

    private String naam;
    public ArrayList<Adres> adressen;
    public ArrayList<Adres> resu<

    public AdresLijst(String naam) {
        this.naam = naam;
        this.adressen = new ArrayList<Adres>();
    }

    public String getNaam() {
        return naam;
    }

    public void adresToevoegen(Adres adres) {
        this.adressen.add(adres);
    }

    public void adresVerwijderen(Adres adres) {
        this.adressen.remove(adres);
    }

    public int aantalAdressen() {
        System.out.println("Er zitten "   adressen.size()   " adressen in deze lijst");
    }

    public AdresLijst zoekNaam(String query) {
        result = new ArrayList<Adres>();
        for(Adres adres : adressen) {
            if(adres.getNaam().startsWith(query) == true) {
                this.result.add(adres);
            }
        }
        return resu<
    }

}
  

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

1. result есть ArrayList<Adres> , но метод объявляет возврат a AdresLijst .

2. Как сказал luk, тип, который вы возвращаете из body ( ArrayList<Adres> ) вашего метода, отличается от того, который вы установили в своем определении ( AdresLijst ) . Вы должны изменить один из них в соответствии с вашим желаемым поведением.

Ответ №1:

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

Проблема

В вашем zoekNaam методе возвращаемый тип объявляется как AdresLijst . Хотя концептуально a List<Adres> sure звучит как AdresLijst , компилятор этого не знает, и система ввода не работает таким образом: С точки зрения компилятора это оружие и бабки (они совершенно не связаны; a List<Adres> не является an AdresLijst , а an AdresLijst не является a List<Adres> , и ни один из них не может быть преобразован в другой автоматически).

Итак, когда вы return resu< используете этот метод с результатом a List<Adres> , компилятор жалуется: нет — вам нужно вернуть an AdresLijst , а не a List<Adres> .

Как это исправить

Вариант 1 — создать новый AdresLijst объект и настроить его result поле с соответствующим материалом. Но это, вероятно, не очень хорошая идея:

У вас есть более фундаментальная проблема с дизайном. Ваши поля — это состояние вашего адреса. Ваш zoekNaam вызов изменяет это состояние — он изменяет result поле. Это означает, что поиск не является «мимолетным» — поиск изменяет список.

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

Сначала вам нужно избавиться от этого result поля; оно не должно быть частью состояния списка (это «мимолетный» аспект: некоторые вызовы кода zoekNaam и возвращает результат. Код AdresLijst не должен запоминать результат, кто бы вам ни звонил, он должен получать результаты и сохранять их, или печатать их, или выражать их в интерпретирующей танцевальной форме — это не ваша работа беспокоиться о том, что они с этим делают. Ваша задача — просто запустить поиск и предоставить результаты).

Затем либо измените возвращаемый тип на List<Adres> , либо создайте новый AdresLijst объект и инициализируйте его adressen значение с помощью результата поиска:

 // now that result is no longer a field, make a local var instead:
List<Adres> result = new ArrayList<Adres>();
// ... rest of your zoekNaam, but remove 'return resu<'

// and now we make a new AdresLijst object,
// give it a proper name..
AdresLijst out = new AdresLijst(this.naam   " (Zoekresultaten)");

// add all our results to it...
out.adressen.addAll(result);

// and return it
return out;
  

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

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

2. Быстрое отслеживание: в тестах, добавленных для назначения, появляется новая ошибка. Однако это больше не ошибка компиляции. java.lang. Исключение NullPointerException: невозможно вызвать «java.util. ArrayList.add(Object)», потому что «this.result» равно нулю в строке 39: this.result.add(adres); есть идеи?

3. Вы не сделали того, что я вам сказал — this.result явно ссылается на поле result (справа вверху). Эти поля необходимо удалить. Тогда просто вызовите эту вещь result .

4. Ах, да. Вы правы, из-за «этого»., он пропустил локальную переменную. Теперь это действительно работает. Спасибо

Ответ №2:

Ваша сигнатура метода public AdresLijst zoekNaam(String query) должна возвращать a AdresLijst , но возвращает a ArrayList<Adres> .
Вы должны либо изменить сигнатуру метода на :

 public ArrayList<Adres> zoekNaam(String query)
  

Либо измените возвращаемое значение на нужный вам тип.

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

1. return this; здесь нет правильного ответа. Это устраняет ошибки компилятора, но тогда метод zoekNaam не делает ничего заметного (он выполняет поиск; результаты поиска будут полностью недоступны). Возможно, голландские имена сбили вас с толку 🙂