2015-05-03 3 views
0

Прежде всего, довольно новый в java, извините, если это простой вопрос.Абстрактный класс возврата в интерфейсе

Я реализовал абстрактный класс и два класса, которые его расширяют.

public abstract class Lado{ 
//body 
} 

и две другие классы с этой формой, например

public class Arista extends Lado 
{ //body 
} 

так, никакой проблемы, теперь я не иметь интерфейс, определенный как это.

public interface Grafo 
{ //body 
    public List<Lado> lados(); 
    //more body 
} 

имеет вы видите интерфейс возвращает список класса Ладо, но в моей реализации я должен возвращать список класса Arista или второго класса (по другой реализации интерфейса)

в кодовая база, что я должен использовать для реализации интерфейса имеет реализацию ЛАДОСА(), как этот

public List<Lado> lados() { 
     return lados; 
    } 

с ЛАДОС, определенный в моем коде как

private List<Arista> lados; 

и инициализируется

lados = new LinkedList<Arista>(); 

теперь, конечно, возвращение дает ошибку

GrafoNoDirigido.java:141: error: incompatible types 
    return lados; 
     ^
    required: List<Lado> 
    found: List<Arista> 
1 error 

Я не могу показаться, чтобы найти, как это исправить без изменения базового кода, который был дан мне (и Я не могу изменить его). Я знаю, что я не могу создать экземпляр абстрактного объекта класса, а реализация абстрактного класса имеет значения и функции, которые нет в абстрактном классе.

Также я не могу использовать переопределение по той же причине, что я не могу изменить свои подписи функций в своих реализациях.

Буду признателен за вашу помощь, спасибо.

Если что-то читает странно, пожалуйста, дайте мне знать.

-------------------- EDIT --------- Lado абстрактного класса.

public abstract class Lado 
{ 
    private String id; 
    private double peso; 

    public Lado(String id, double peso) { 
     this.id = id; 
     this.peso = peso; 
    } 

    public String getId() { 
     return id; 
    } 

    public double getPeso() { 
     return peso; 
    } 

    public abstract String toString(); 

} 

Arista подкласс

public class Arista extends Lado 
{ 
    private Vertice u; 
    private Vertice v; 

    public Arista(String id, double peso, Vertice u, Vertice v){ 
     super(id , peso); 
     this.u = u; 
     this.v = v; 
    } 

    public Vertice getExtremo1() { 
    return u; 
    } 

    public Vertice getExtremo2() { 
    return v; 
    } 


    public String toString() { 
    String s = "string"; 
    return s; 
    } 

} 

Тогда, если я возвращать List<Lado> если у попытаться сделать getExtremo1() это doenst найти символ на компиляции (нет несуществующие на классе Ладо), пытался бросить список вывода как List<Arista>, но он тоже не работал правильно.

+3

решение заключается в том, чтобы изменить тип возврата в интерфейсе 'Grafo' как' List '. Однако, если вы не можете изменить это, вы застряли. –

+0

Q: Какой из ваших классов на самом деле * реализует * Grafo? – FoggyDay

+0

@FoggyDay класс реализован в классе GrafoDirigido, а другой называется Digrafo, эта работа работает на 90%. Мне просто нужно, чтобы функция lados() работала правильно. pbabcdefp Да, это работает, к сожалению, я не могу изменить базовую подпись функции, которая была предоставлена ​​мне. Спасибо. – AlejandroDiaz

ответ

0

Попробуйте изменить интерфейс:

Публичный список ЛАДОС();

public List<? extends Lado> lados(); 

- ИЛИ -

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

private List<Lado> lados; 

@Override 
public List<Lado> lados() { 
    // Type of lados is List<Lado>, but we will fill it up with Arista instances... 
    lados = new LinkedList<Lados>(); 
    lados.add(new Arista()); 
    // if Arista has methods that follow the with setter stereotype, ie: public Arista withId(int id) { this.setId(id); return this; } you can in-line create them: 
    lados.add(new Arista() 
       .withId(id) 
       .withName(name) 
    ); 
    Arista arista = new Arista(); 
    lados.add(arista); 
    ... 
    return lados; 
} 

Надежда, что помогает!

+0

Только второй вариант здесь действительно будет работать. –

+0

@LouisWasserman: Я отредактировал и добавил еще один -OR--, который позволит ему не нужен общий тип. – anonymous

+0

Этот новый второй вариант также не работает. –

1

Поскольку класс Artista также класс Ладо, ваша инициализация должна быть

List<Lado> lados = new LinkedList<>(); 
: 
lados.add(new Artista (..)); 
: 
return lados; 
+0

Сообщите мне, если это поможет. – MaxZoom

+0

Он работает, но создает другие проблемы, например, я повторяю в списке, тогда компилятор увидит каждый элемент, как и класс lado, и если мне нужно будет использовать некоторые методы класса Arista, это не сработает. Спасибо за ваше время. – AlejandroDiaz

+0

Когда итерация спросит объект, какой класс он использует с помощью оператора instanceOf. – MaxZoom

0

Проблема в том, что Java не имеет хорошей поддержки «дисперсии» для перечислений (и нет, это не простой вопрос). Посмотрите здесь, в разделе «обходной путь» для решения: https://schneide.wordpress.com/tag/upcast/

-1

Так это ваши ограничения:

  • вы не можете изменить ЛАДОС() метод типа возврата (List<Lado>).
  • вы хотите, чтобы ваше поле, чтобы иметь List<Arista>

1. Копирование массива

public List<Lado> lados() { 
    return new ArrayList<>(lados); 
} 

2. завернув в неизменяемый список *

public List<Lado> lados() { 
    return Collections.unmodifiableList(lados); 
} 

3. Нарисуйте стирание, не делайте этого, это unsafe

Стирание дженериков вашего поля перед его возвращением. Небезопасно, так как если кто-то добавляет объект, который расширяет Lado, но это не Arista, в этом списке у вас будет HeapPolution.

@SuppressWarnings("unchecked") 
public List<Lado> lados() { 
    return (List)lados; 
} 
+0

Это ужасная идея, которая ставит под угрозу безопасность типов и может привести к загрязнению кучи. – Radiodef

+0

Является ли это компиляция, не является проблемой. 'class Foo расширяет Lado {} новый GraphoImpl(). lados(). add (new Foo());' Это не ** безопасно и ** никто ** должен его использовать. – Radiodef

+0

ОК, вы беспокоитесь о том, кто-то изменил этот список. отметил пункт. Я изменил ответ, чтобы отразить ваш вклад. –

0

Если вы не можете изменить либо тип метод возврата или объявление переменной, вы можете вернуть копию:

public List<Lado> lados() { 
    return new LinkedList<Lado>(lados); 
} 

Или вы можете вернуть обертку:

public List<Lado> lados() { 
    return java.util.Collections.unmodifiableList(lados); 
} 
+0

unmodifiableList? Я так не думаю. Все хорошо :) –

+0

Копирование работает, просто нужно проверить, если, когда я поймаю этот возврат, я могу увидеть свойства проверки или функции класса Arista. Спасибо за ваше время. – AlejandroDiaz

Смежные вопросы