#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>
, но метод объявляет возврат aAdresLijst
.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 не делает ничего заметного (он выполняет поиск; результаты поиска будут полностью недоступны). Возможно, голландские имена сбили вас с толку 🙂