Tipos acotados con genéricos en Java

Puede haber ocasiones en las que desee restringir los tipos que se pueden usar como argumentos de tipo en un tipo parametrizado. Por ejemplo, es posible que un método que opera con números solo quiera aceptar instancias de Números o sus subclases. Para esto están los parámetros de tipo acotado. 

  • A veces no queremos que se parametrice toda la clase. En ese caso, podemos crear un método genérico de Java. Dado que el constructor es un tipo especial de método, también podemos usar tipos genéricos en los constructores.
  • Supongamos que queremos restringir el tipo de objetos que se pueden usar en el tipo parametrizado. Por ejemplo, en un método que compara dos objetos y queremos asegurarnos de que los objetos aceptados son Comparables.
  • La invocación de estos métodos es similar al método ilimitado, excepto que si intentamos usar cualquier clase que no sea comparable, arrojará un error de tiempo de compilación.

¿Cómo declarar un parámetro de tipo acotado en Java? 

  1. Enumere el nombre del parámetro de tipo,
  2. Junto con la palabra clave extends
  3. Y por su cota superior. (que en el siguiente ejemplo c es A .)

Sintaxis

<T extends superClassName>

Tenga en cuenta que, en este contexto, extends se usa en un sentido general para significar «extiende» (como en las clases). Además, esto especifica que T solo puede ser reemplazado por superClassName o subclases de superClassName. Por lo tanto, una superclase define un límite superior inclusivo.

Tomemos un ejemplo de cómo implementar tipos acotados (superclase extendida) con genéricos.

Java

// This class only accepts type parameters as any class
// which extends class A or class A itself.
// Passing any other type will cause compiler time error
 
class Bound<T extends A>
{
     
    private T objRef;
     
    public Bound(T obj){
        this.objRef = obj;
    }
     
    public void doRunTest(){
        this.objRef.displayClass();
    }
}
 
class A
{
    public void displayClass()
    {
        System.out.println("Inside super class A");
    }
}
 
class B extends A
{
    public void displayClass()
    {
        System.out.println("Inside sub class B");
    }
}
 
class C extends A
{
    public void displayClass()
    {
        System.out.println("Inside sub class C");
    }
}
 
public class BoundedClass
{
    public static void main(String a[])
    {
         
        // Creating object of sub class C and
        // passing it to Bound as a type parameter.
        Bound<C> bec = new Bound<C>(new C());
        bec.doRunTest();
         
        // Creating object of sub class B and
        // passing it to Bound as a type parameter.
        Bound<B> beb = new Bound<B>(new B());
        beb.doRunTest();
         
        // similarly passing super class A
        Bound<A> bea = new Bound<A>(new A());
        bea.doRunTest();
         
    }
}
Producción

Inside sub class C
Inside sub class B
Inside super class A

Ahora, estamos restringidos solo al tipo A y sus subclases, por lo que arrojará un error para cualquier otro tipo de subclases.

Java

// This class only accepts type parameters as any class
// which extends class A or class A itself.
// Passing any other type will cause compiler time error
 
class Bound<T extends A>
{
     
    private T objRef;
     
    public Bound(T obj){
        this.objRef = obj;
    }
     
    public void doRunTest(){
        this.objRef.displayClass();
    }
}
 
class A
{
    public void displayClass()
    {
        System.out.println("Inside super class A");
    }
}
 
class B extends A
{
    public void displayClass()
    {
        System.out.println("Inside sub class B");
    }
}
 
class C extends A
{
    public void displayClass()
    {
        System.out.println("Inside sub class C");
    }
}
 
public class BoundedClass
{
    public static void main(String a[])
    {
        // Creating object of sub class C and
        // passing it to Bound as a type parameter.
        Bound<C> bec = new Bound<C>(new C());
        bec.doRunTest();
 
        // Creating object of sub class B and
        // passing it to Bound as a type parameter.
        Bound<B> beb = new Bound<B>(new B());
        beb.doRunTest();
 
        // similarly passing super class A
        Bound<A> bea = new Bound<A>(new A());
        bea.doRunTest();
         
        Bound<String> bes = new Bound<String>(new String());
        bea.doRunTest();
    }
}

Producción :

error: type argument String is not within bounds of type-variable T

Límites múltiples

Los parámetros de tipo acotado se pueden usar con métodos, así como con clases e interfaces.

Java Generics también admite múltiples límites, es decir, en este caso, A puede ser una interfaz o una clase. Si A es clase, entonces B y C deberían ser interfaces. No podemos tener más de una clase en múltiples límites.

Sintaxis:

<T extends superClassName & Interface>

Java

class Bound<T extends A & B>
{
     
    private T objRef;
     
    public Bound(T obj){
        this.objRef = obj;
    }
     
    public void doRunTest(){
        this.objRef.displayClass();
    }
}
 
interface B
{
    public void displayClass();
}
 
class A implements B
{
    public void displayClass()
    {
        System.out.println("Inside super class A");
    }
}
 
public class BoundedClass
{
    public static void main(String a[])
    {
        //Creating object of sub class A and
        //passing it to Bound as a type parameter.
        Bound<A> bea = new Bound<A>(new A());
        bea.doRunTest();
         
    }
}
Producción

Inside super class A

Este artículo es una contribución de Saket Kumar . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks. Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *