Classificar List

4 respostas
zVictor

estou fazendo um mini-jogo (Sokoban|Box-World).
como ele vai ser avaliado pelo meu professor de OO, tenho q fazer td rigorosamente orientado a obj.

No meu projeto, tenho varias classes para os diversos elementos do jogo (Personagem, Caixa, Alvo…) e cada classe implementa interfaces respectivas às suas propriedades (Movel, Sobreponivel…). Tais objetos sao instanciados e colocados em uma List respectiva a cada fase do jogo.

A questão é que, quando o personagem for se mover, ele precisa saber se o objeto que esta a sua frente é Movel ou nao, e se o objeto na frente deste outro objeto é Sobreponivel (Ex.: o personagem precisa saber se é uma caixa na sua frente, e se na frente da caixa tem um alvo, parede ou apenas um ‘Fundo’).

Minhas duvidas:

  • posso classificar ou filtrar os objetos da minha lista a partir da interface ou outra propriedade que ele carrega?
  • qual seria o meio correto, nesse caso, de perguntar a outro objeto se ele é, por exemplo, Movel?

4 Respostas

Alkamavo

pode usar o comando

if (name instanceof type) {
	type new_name = (type) name;

ou seja podes perguntar se um objecto é do tipo de uma dada interface…k implementa um objecto movel…
POr exemplo se tivers uma interface pessoa podes perguntar se um dado objecto é da interface pessoa com este comando isso devolve um booleano

if ( alkamavo instaceof pessoa){ System.out.println(" Viva ALkamavo"); }

sergiotaborda

zVictor:

Minhas duvidas:

  • posso classificar ou filtrar os objetos da minha lista a partir da interface ou outra propriedade que ele carrega?
  • qual seria o meio correto, nesse caso, de perguntar a outro objeto se ele é, por exemplo, Movel?

Para filtrar vc pode criar um classificador e aplicá-lo a uma coleção

public interface Classification<C,T> {

    public C classify ( T object);
 
}

public interface BooleanClassification<T> implements Classification<Boolean,T> {

    public Boolean classify ( T object);
 
}

public class Filter {

  public static <T> Collection<T> filter ( Collection <T> all , Classification<Boolean, T> classification ){

           Collection<T> result = new LinkedList<T>();
           for (T t : all ){
                  if (classify (t)){
                        result.add(t);
                  }
           }
           return result;
  }

}

// uso 

List<Elemento> elementos = ...

List<Elemento> moveis = Filter.filter (elementos , new BooleanClassifier<Elemento>(){

 public Boolean classify (Elemento el){
        return el.canMove();
}
  })

Para poder saber se o elemento é movel ou qq outra coisa, vc pergunta ao elemento

elemento.canMove()

Se existe uma interface Movel que extende Elemento, então canMove sempre retornará true para
os elementos desse tipo. Por outro lado qualquer elemento que tem canMove()== true deve implementar Movel.

Tente evitar o uso de instanceof o mais possivel.

zVictor

muito esclarecedoras estas respostas. obrigado.
porem, fiquei com uma duvida quanto a implementação do ‘classificador’.
Para utiliza-lo, eu precisaria criar o metodo canMove() em todos os objetos. A classe Parede, por exemplo, teria um canMove() de retorno false, certo?

Assim sendo, eu praticamente nao precisaria mais de interfaces no meu projeto, bastaria colocar tds os métodos na superclasse, abstrata.
Entretanto, se formos analisar uma futura reutilização das classes, esses métodos seriam inuteis em muitos casos.
Não posso fazer com que apenas os objetos que se movam e que utilizem a interfacel Movel tenham métodos respectivos a essa características? Em outras palavras, o ideal era que eu pudesse organizar essa lista apartir de suas caracteristicas, sem ter incluir métodos booleanos em tds as classes e sem usar intanceof.

Basicamente, o problema ja foi resolvido pelos usuarios, apenas me resta essa duvida.

B

Talvez você queira usar a API de Reflection nesses casos.

A classe Class tem o método getInterfaces(), com ele você poderia perguntar para o objeto se a classe dele implementa Móvel.

De qualquer modo, canMove() é a mais OO das opções.

Outra opção é não implementar canMove() nas classes que não são móveis. Isso geraria um NoSuchMethodException. Mas dependendo da implementação, isso pode não compilar.

Ainda outro modo, fazer todos os objetos herdarem de uma classe abstrata ObjetoDeJogo ou algo parecido, que teria um canMove() com retorno false.

Você disse que não precisaria mais de interfaces desse modo, com classes abstratas. Te digo que interfaces não são para definir métodos, são pra definir comportamentos, e nestes sim é que você pode(ou não) ter métodos.

Implementar a interface Móvel significaria que espera-se o tal o comportamento móvel dos objetos que o implementam, não somente que canMove() retorne true, mas que também outras pré-condições, e métodos para usar o objeto, estejam presentes. Para essas classes você acreditaria cegamente que elas são móveis, sem precisar de qualquer checagem prévia.

Criado 10 de junho de 2008
Ultima resposta 11 de jun. de 2008
Respostas 4
Participantes 4