Cómo implementar el método suma con un argumento de tipo comodín en su parámetro
Recuerde que el propósito del método
suma
en la fi gura 18.14 era obtener el total de cualquier tipo de objetos
Number
almacenados en un objeto
ArrayList
. Creamos un objeto
ArrayList
de objetos
Number
que contenía
objetos
Integer
y
Double
. Los resultados de la fi gura 18.14 demuestran que el método
sumar
trabajó correc-
tamente. Dado que el método
sumar
puede obtener el total de los elementos de un objeto
ArrayList
de objetos
Number
, podríamos esperar que el método también funcionara para objetos
ArrayList
que contengan elemen-
tos de sólo un tipo numérico, como
ArrayList< Integer >
. Así, modifi camos la clase
TotalNumeros
para crear
un objeto
ArrayList
de objetos
Integer
y pasarlo al método
sumar
. Al compilar el programa, el compilador
genera el siguiente mensaje de error:
sumar(java.util.ArrayList<java.lang.Number>) in TotalNumerosErrores
cannot be applied to (java.util.ArrayList<java.lang.Integer>)
Aunque
Number
es la superclase de
Integer
, el compilador no considera que el tipo parametrizado
ArrayList
< Number >
sea un supertipo de
ArrayList< Integer >
. Si lo fuera, entonces toda operación que pudiéramos
realizar en
ArrayList< Number >
funcionaría también en un
ArrayList< Integer >
. Considere el hecho de
que puede sumar un objeto
Double
a un
ArrayList< Number >
, debido a que un
Double
es un
Number
, pero no
se puede sumar un objeto
Double
a un
ArrayList< Integer >
, ya que un
Double
no es un
Integer
. Por ende,
no es válida la relación de los subtipos.
¿Cómo creamos una versión más fl exible del método
sumar
que pueda obtener el total de los elementos de
cualquier objeto
ArrayList
que contenga elementos de cualquier subclase de
Number
? Aquí es donde son impor-
tantes los
argumentos tipo comodín
. Los comodines nos permiten especifi car parámetros de métodos, valores
de retorno, variables o campos, etc., que actúan como supertipos de los tipos parametrizados. En la fi gura 18.15,
el parámetro del método
suma
se declara en la línea 50 con el tipo:
ArrayList< ?
extends
Number >
Un argumento tipo comodín se denota mediante un signo de interrogación (
?
), que por sí solo representa un
“tipo desconocido”. En este caso, el comodín extiende a la clase
Number
, lo cual signifi ca que el comodín tiene
un límite superior de
Number
. Por ende, el argumento de tipo desconocido debe ser
Number
o una subclase de
Number
. Con el tipo del parámetro que se muestra aquí, el método
sumar
puede recibir un argumento
ArrayList
que contenga cualquier tipo de
Number
, como
ArrayList< Integer >
(línea 20),
ArrayList< Double >
(línea
33) o
ArrayList< Number >
(línea 46).
En las líneas 11 a 20 se crea e inicializa un objeto
ArrayList< Integer >
llamado
listaEnteros
, se
imprimen en pantalla sus elementos y se obtiene el total de los mismos mediante una llamada al método
sumar
(línea 20). En las líneas 24 a 33 se realizan las mismas operaciones para un objeto
ArrayList< Double >
llamado
listaDouble
. En las líneas 37 a 46 se realizan las mismas operaciones para un objeto
ArrayList< Number >
llamado
listaNumeros
, el cual contiene objetos
Integer
y
Double
.
En el método
sumar
(líneas 50 a 59), aunque los tipos de los elementos del argumento
ArrayList
no son
directamente conocidos para el método, se sabe que por lo menos son de tipo
Number
, ya que el comodín se
especifi có con el límite superior
Number
. Por esta razón se permite la línea 56, ya que todos los objetos
Number
tienen un método
doubleValue
.
Aunque los comodines proporcionan una fl exibilidad al pasar tipos parametrizados a un método, también
tienen ciertas desventajas. Como el comodín (?) en el encabezado del método (línea 50) no especifi ca el nombre
de un parámetro de tipo, no se puede utilizar como nombre de tipo en el cuerpo del método (es decir, no pode-
mos reemplazar
Numero
con
?
en la línea 55). Sin embargo, podríamos declarar el método
sumar
de la siguiente
manera:
public static
<T
extends
Number>
double
sumar( ArrayList< T > lista )
lo cual permite al método recibir un objeto
ArrayList
que contenga elementos de cualquier subclase de
Number
.
Después, podríamos usar el parámetro de tipo
T
en el cuerpo del método.
Si el comodín se especifi ca sin un límite superior, entonces sólo se pueden invocar los métodos del tipo
Object
en valores del tipo del comodín. Además, los métodos que utilizan comodines en los argumentos de
tipo de sus parámetros no pueden utilizarse para agregar elementos a una colección a la que el parámetro hace
referencia.
18.8 Comodines en métodos que aceptan parámetros de tipo
785
18_MAQ_CAP_18_DEITEL.indd785
4/19/081:30:51AM