Comparable em classe filha

8 respostas
allexandrejr

Galera,

Tenho uma classe tarefa que implementa o comparable, assim:

public class Tarefa implements Comparable<Tarefa>

E uma classe TarefaConcluida que extende a classe Tarefa.

Ao tentar implementar o Comparable nessa classe fillha, assim:

public class TarefaConcluida extends Tarefa implements Comparable<TarefaConcluida>

Dá um erro informando que a interface não permite a implementação do Comparable com mais de uma argumento.

Alguém poderia me dar uma luz?

8 Respostas

B

Essa é uma das limitações do Java causado pelo apagamento de tipos do Generics:

http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ401

Pro teu caso a solução é não usar o Comparable na classe filha.

allexandrejr

O problema é que as classes das Tarefas serão usadas em listas encadeadas que só aceitam tipos comparáveis como parâmetro. :cry:

Assim:

private ListaEncOrd<Tarefa> tarefasAgendadas; private ListaEncOrd<TarefaConcluida> tarefasConcluidas;

Quando não uso, o java não aceita.

Por enquanto estou fazendo sem herança entre Tarefa e TarefaConcluída.

Mas acho que o correto seria usar herança, não é?

mauricioadl

Não eh so escrever o metodo compareTo?. Nao coloque o implements Comparable na filha, pois ela ja eh comparable por seu pai

[]'s

DavidUser

O mauricioadl disse tudo, não faz nem mesmo sentido o segundo implements em TarefaConcluida.

Dica:
Se as classes Tarefa e TarefaConcluida tiverem as mesma funcionalidade (a única diferença real é o tipo) é a hora de repensar a modelagem, você pode por exemplo incluir um atributo para especificar o estado do objeto Tarefa, isso se as próprias estruturas não fazem o trabalho de organizar os estados, cuidado com a repetição.

allexandrejr

mauricioadl, se eu não colocar o implements na filha, qdo tento declarar um atributo do tipo TarefaConcluída o java diz que ela não implementa o comparable. :wink:

Bom, acho que, nessa situação, realmente não dá pra usar herança.

É um exercício de Estrutura de Dados. E o prof pediu que houvesse as duas classes.

Vou deixá-las sem herança mesmo.

Agradeço a ajuda de todos.

DavidUser

O problema fica então com o uso de generics na sua lista, um modo de contornar segue no exemplo:

class ListaEncOrd&lt;T&gt; {
	LinkedList&lt; Comparable&lt;Object&gt; &gt; list;
	
	public void add(Comparable&lt;Object&gt; item) {
		list.add(item);
	}
}


class Tarefa implements Comparable&lt;Object&gt; {
	protected String description = "";
	
	@Override
	public int compareTo(Object o) {
		if (o instanceof Tarefa)
			return description.compareTo( ((Tarefa) o).description);
		else
			throw new InvalidParameterException();
	}
}

class TarefaConcluida extends Tarefa {
}

public class Main {
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ListaEncOrd&lt;Tarefa&gt; tarefas = new ListaEncOrd&lt;Tarefa&gt;();
		
		tarefas.add(new Tarefa());
		tarefas.add(new Tarefa());
		
		ListaEncOrd&lt;TarefaConcluida&gt; tarefasConcluidas = new ListaEncOrd&lt;TarefaConcluida&gt;();
		
		tarefasConcluidas.add(new TarefaConcluida());
		tarefasConcluidas.add(new TarefaConcluida());
	}
}
DavidUser

Ainda sim pelo que foi passado não vejo necessidade para o uso de Generics para criação da sua coleção:

import java.security.InvalidParameterException;
import java.util.LinkedList;


class ListaEncOrd {
	LinkedList&lt; Comparable&lt;Object&gt; &gt; list;
	
	public ListaEncOrd() {
		list = new LinkedList&lt; Comparable&lt;Object&gt; &gt;();
	}
	
	public void add(Comparable&lt;Object&gt; item) {
		list.add(item);
	}
}


class Tarefa implements Comparable&lt;Object&gt; {
	protected String description = "";
	
	@Override
	public int compareTo(Object o) {
		if (o instanceof Tarefa)
			return description.compareTo( ((Tarefa) o).description);
		else
			throw new InvalidParameterException();
	}
}

class TarefaConcluida extends Tarefa {
	
	@Override
	public int compareTo(Object o) {
		if (o instanceof TarefaConcluida)
			return super.compareTo(o);
		else if (o instanceof Tarefa)
			return -1;
		else
			throw new InvalidParameterException();
	}
}

public class Main {
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ListaEncOrd tarefas = new ListaEncOrd();
		
		tarefas.add(new Tarefa());
		tarefas.add(new Tarefa());
		
		ListaEncOrd tarefasConcluidas = new ListaEncOrd();
		
		tarefasConcluidas.add(new TarefaConcluida());
		tarefasConcluidas.add(new TarefaConcluida());
	}
}
DavidUser

Ainda pode resolver o problema definido o tipo básico com que a sua Coleção pode trabalhar ao invés de utilizar Object, definido no lugar de Object o tipo básico.
Se todos tipos com que a sua coleção pode trabalhar são tarefas (Tarefa e suas extensões), ficaria algo assim:

import java.util.LinkedList;


class ListaEncOrd {
	LinkedList< Comparable<Tarefa> > list;
	
	public ListaEncOrd() {
		list = new LinkedList< Comparable<Tarefa> >();
	}
	
	public void add(Comparable<Tarefa> o) {
		list.add(o);
	}
}


class Tarefa implements Comparable<Tarefa> {
	protected String description = "";
	
	@Override
	public int compareTo(Tarefa o) {
		return description.compareTo( ((Tarefa) o).description);
	}
}

class TarefaConcluida extends Tarefa {
	
	@Override
	public int compareTo(Tarefa o) {
		if (o instanceof TarefaConcluida)
			return super.compareTo(o);
		else
			return -1; //as que nao sao TarefaConcluida devem ser antecessoras
	}
	
}

public class Main {
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ListaEncOrd tarefas = new ListaEncOrd();
		
		tarefas.add(new Tarefa());
		tarefas.add(new Tarefa());
		
		ListaEncOrd tarefasConcluidas = new ListaEncOrd();
		
		tarefasConcluidas.add(new TarefaConcluida());
		tarefasConcluidas.add(new TarefaConcluida());
	}
}
Criado 23 de fevereiro de 2013
Ultima resposta 26 de fev. de 2013
Respostas 8
Participantes 4