Genéricos e conjuntos

Vocês concordam que as alternativas corretas são C,D e G apenas? Pra mim a alternativa A tb é correta.

Given:

class A {} class B extends A {} class C extends A {} class D extends B {}

Which three statements are true? (Choose three.)

A. The type List is assignable to List.
B. The type List is assignable to List
.
C. The type List is assignable to List<?>.
D. The type List is assignable to List<? extends B>.
E. The type List<? extends A> is assignable to List
.
F. The type List is assignable to any List reference.
G. The type List<? extends B> is assignable to List<? extends A>.

Dei uma olhada (passei o código abaixo para o compilador), e realmente as alternativas corretas são A, C, D e G.

import java.util.*;
class A {}
class B extends A {}
class C extends A {}
class D extends B {}
class Assignable {
    public static void main(String[] args) {
	    List list = new ArrayList();
		List<A> listA = new ArrayList<A>();
		List<B> listB = new ArrayList<B>();
		List&lt;Object&gt; listObject = new ArrayList&lt;Object&gt;();
		List&lt;D&gt; listD = new ArrayList&lt;D&gt;();
		List&lt;?&gt; listWhat = new ArrayList&lt;Object&gt;();
		List&lt;? extends A&gt; listExtendsA = new ArrayList <B>();
		List&lt;? extends B&gt; listExtendsB = new ArrayList &lt;D&gt;();
		
//A. The type List<A> is assignable to List. =&gt; OK
		list = listA;
//B. The type List<B> is assignable to List<A>. =&gt; Incompatible types
		listA = listB;
//C. The type List&lt;Object&gt; is assignable to List&lt;?&gt;. =&gt; OK
		listWhat = listObject;
//D. The type List&lt;D&gt; is assignable to List&lt;? extends B&gt;. =&gt; OK
		listExtendsB = listD; 
//E. The type List&lt;? extends A&gt; is assignable to List<A>.
		listA = listExtendsA; // =&gt; incompatible types
//F. The type List&lt;Object&gt; is assignable to any List reference. 
		list = listObject; // =&gt; OK
		listA = listObject; // =&gt; incompatible types
//G. The type List&lt;? extends B&gt; is assignable to List&lt;? extends A&gt;. 	=&gt; OK
		listExtendsA = listExtendsB;
    }
}

Mais um erro encontrado no Killer. :frowning:

[quote=osmio]Até onde eu sei, Generics do tipo:

List<? extends TipoDeClasse>

só pode receber objetos que EXTENDAM TipoDeClasse. Não classes TipoDeClasse.

Por exemplo, na minha concepção isso seria válido:


ClasseA {}
ClasseB extends A {}
ClasseC extends B {}

List<? extends A> lista = new ArrayList<B>();
List<? extends A> lista = new ArrayList<C>();

Mas isso, pra mim, não seria válido:

List<? extends A> lista = new ArrayList<A>();

Agora, sinceramente não sei te dizer se o compilador deixa passar ou não.
Nunca testei algo assim.

Tenta atualizar a versão do update do jdk. Talvez isso já tenha sido corrigido e ainda não sabemos.

Até!

[/quote]

Isso é perfeitamente válido:

Este “? extends A”, quer dizer “A ou qualquer uma de suas subclasses”.

ih vei no killer tem altos erro, uns até sem logica,
por isso que quando eu estudo os simulados, eu testo todos,
:wink:

assim… qdo nao queremos “erros” compramos… o whizlabs ta a venda… e nao foi encontrando nenhum erro nas questoes… :smiley:

assim… eu tenho o Whizlabs… a única coisa que fiz foi uma constatação, apesar de muito bom eu não me prendo a apenas esse simulado.

Só mais uma sujestão :
esse tipo de criação de um objecto tem um propósito importante para passagens por referências,ou seja caso vc tenha:

[code]
class Animal{
}
class Dog extends Animal{
}
class Text{
public static void main(String…a){
List<? extends Animal> lista_animal=new ArrayList();
List lista_dog=new ArrayList();
//agora vc pode tranquillamente fazer
lista_animal=lista_dog;//vc esta referenciando uma Objecto listaDog

//agora o contrario
List<? super Dog> lista_dog2=new ArrayList();
List lista_animal2=new ArrayList();
lista_dog2=lista_animal2;//agora vc consegue referenciar algo que esta acima na arvore de heranca!!que normalmente não é permitido em java

}
}
Só mesmo para acrescentar :-o bom estudos!!

}

Isso não é válido. Na hora de criar o elemento o tipo tem que ser conhecido. Só na hora de referenciar é que ele não precisa ser conhecido. Ou seja:

// Válido. É criado um ArrayList cujos elementos são do tipo A.
List<? extends A> lista = new ArrayList<A>();

// Inválido é criado um ArrayList cujos elementos são de um tipo desconhecido.
// O compilador reclama: Você tem que saber que tipo você vai criar.
List<? extends A> lista = new ArrayList<? extends A>();

Bom pelo que a gente viu no metodo getObject B é uma classe concreta ja que usa operador new nela, e tipo
classes concretas não podem ter metodos abstracts…além do mais se ela fosse uma classe abstrata tbem…
metodos aabstract não terminam com chaves e sim com parenteses…
lembre-se que vc está especificando apenas sua assinatura…não seu corpo…por iss ele é abstrato.

Até onde eu sei, Generics do tipo:

List<? extends TipoDeClasse>

só pode receber objetos que EXTENDAM TipoDeClasse. Não classes TipoDeClasse.

Por exemplo, na minha concepção isso seria válido:


ClasseA {}
ClasseB extends A {}
ClasseC extends B {}

List<? extends A> lista = new ArrayList<B>();
List<? extends A> lista = new ArrayList<C>();

Mas isso, pra mim, não seria válido:

List<? extends A> lista = new ArrayList<A>();

Agora, sinceramente não sei te dizer se o compilador deixa passar ou não.
Nunca testei algo assim.

Tenta atualizar a versão do update do jdk. Talvez isso já tenha sido corrigido e ainda não sabemos.

Até!

[quote=victorwss]
Isso é perfeitamente válido:

Este “? extends A”, quer dizer “A ou qualquer uma de suas subclasses”.[/quote]

Imagine essa estrutura:

abstract class A {
    public abstract void facaAlgo();
}

B extends A {
    public abstract void facaAlgo() { }
}

class Teste {

    public static void main(String... args) {
        List<? extends A> lista = new ArrayList<? extends A>();

        // nesse momento eu faço uma chamada ao metodo getObjeto que me 
        // retorna um objeto tipo A. até aqui sem problemas. 
        // mas A é uma classe abstrata que contem métodos abstratos.
        // como posso garantir que o objeto que esta vindo é uma subclasse 
        // de A e que implemente seus métodos abstratos?
        // se eu tentar criar uma instancia de A, não vai funcionar
        lista.add(getObjeto());
    }

    A getObjeto() {
        return new B();
    } 

}