camps.add(newKiteSurf()); camps.add(newWindSurf()); camps.addAll(windSurfs2); camps.addAll(surf2); camps.addAll(kiteSurf2); Campeonatos[]campS= newCampeonatos[3]; campS[0]= newSurf(); campS[1]= newWindSurf(); campS[2]= newKiteSurf(); Campeonatos[]campKS= { newSurf(), newWindSurf(), new KiteSurf() }; Coma demontracao acima vemos que e possivel arrayList armazenarsubclasses em um conjunto a partir de uma superclasse especificada. Ocodigo acima compila e executa normalmente. Voltandoa questao que questionamos a pouco quando os problemas relacionadosa polimorfismo, vemos que neste momento os conjuntos arrayListespecificados como arrayList nao geram erros durante a compilacaocomprovando que e possivel trabalhar com um conjunto de umasuperClasse que por sua vez podera obter varias subclassesinternamente. Averdade e que o compilador trata de forma diferente os conjuntosarray e arrayList. Em quanto o primeira nao possui um tratamento enao gera erro ao trabalharmos com varios tipos de elementosdiferentes (Surf, WindSurf e KiteSurf) em um mesmo conjunto, o mesmonao ocorrer trabalhando com arrayList. A partir da classificacaopor meio dos genericos o compilador so adiciona um elemento(subclasse) em um conjunto caso o programador informe que realmentequer que isso ocorra. Desta forma nao ira tirar os beneficios deuma programacao bem estruturada por polimorfismo. A principio ocompilador ira trabalhar em um conjunto esperando somente um tipo deelemento. Para que ele aceite outros tipos de elementos aceitos pelopolimorfismo o programador devera informar ao compilador que irarealizar tal procedimento utilizando o caracter (?) tambem chamadode coringa. publicvoid realizarEventosC(ArrayList<? extendsCampeonatos> listaDeEventos){ System.out.println("arrayList");//naosepodeadicionaraqui for(Campeonatos c: listaDeEventos){ c.preRequisistos(); } } publicvoidrealizarEventosSurf(ArrayList<? superSurf> listaDeEventos){ System.out.println("arrayList"); listaDeEventos.add(newSurf()); } Conformeexemplo acima,vemos que e possivel a utilizacao do coringa de 2formas diferentes, no primeiro metodo realizaEventosC informaque qualquer elemento que extendaa classe Campeonatos podera ser passada em quanto o segundo metodorealizarEventosSurfinforma ao compilador que qualquer superclasseque entre no relaciomento E-UMcomaclasse Surfequando digo que e qualquer um relacionamento que se enquadra e porporder utilizar inclulsive interfaces. Nao existe como colocar em umparametro de um metodo a expressao <?implements UmaInterface> pormais que possa parecer estranho e a palavra reservada extends quesera utilizada neste momento. Ocoringa pode inclusive ser utilizado para informar que o paramentropodera ser uma lista de qualquer tipo de elemento cconforme abaixo: publicvoidmetodoQuePassaComoParamsListaDeQQElemento(List<?> elemento){ Outrainformacao importante e que apesar de estarmos focando emparamentros de metodos todas estas formas de especificar umconjunto que possua subclasses, superclasses ou de qualquer elemento,podera ser usado tambem para um retorno de um metodo especificoda seguinte foram:publicArrayList<? extendsCampeonatos> realizarEventosC(){...publicArrayList<?superSurf> realizarEventosSurf() {... Aunica ressalva para a utilizacao do croringa e em uma declaracaode uma variavel onde o caractere de interarogaco nao poderaestar presente na parte de instanciacao. Exemplos:ArrayList<?superSurf> listaDeEventos= newArrayList<Campeonatos>();//OKArrayList<Campeonatos>listaDeEventos= newArrayList<<? superSurf>>();//ErroDeclaracoesGenericas Sempreque nos depararmos com uma declaracao generica, depararemos comduas formas diferentes de marcadores, a letra e normalmentemaiuscula entre os operadores de menor que e maior que <E> quesignifica elemento e a letra t normalmente em sua formamaiuscula, <T> que significando tipo. Estasconvencoes servem para deixar como abstrato o elemento ou tipo queo desenvolvedor utilizara quando necessitar em sua declaracaogenerica a utilizacao destas convencoes ajuda inclusive nautilizacao junto com uma IDE que preenche o elemento ou tipo daclasse de acordo com o que tem desenvolvido. Exemplo:classCampeonatos<T> { privateList<T> competidores;//podemsersurfistas,windsurfistas,kiteSurfistas privateintnumeroDeCompetidores; publicCampeonatos(intnumeroCompetidores,List<T> competidores){ //construtorcomas mesmascaracteristicassurfistas,windsurfistas, kiteSurfistas this.competidores= competidores; this.numeroDeCompetidores= numeroCompetidores; } publicT getCompetidor(){ returncompetidores.get(0); } publicvoidsetCompetidores(T competidor){ competidores.add(competidor); } publicvoidpreRequisistos() { System.out.print("necessarioprancha