una resueltos que programacion interfaz interfaces implementacion herencia hacer ejercicios ejemplos como java object generics interface anonymous-types

resueltos - Java: definición de un miembro que amplía la clase A e implementa la interfaz B



public interface java (2)

Puede declarar parámetros de tipo que tienen límites múltiples, como:

public static <T extends A & B> void test(Class<T> clazz)

Pero no puedes declarar una variable que tiene múltiples límites:

private Class<? extends A & B> variable; // doesn''t work

Puede crear una clase abstract C que amplíe A e implemente B , de modo que solo se requiera un límite.

abstract class C extends A implements B {}

Entonces:

private Class<? extends C> variable;

Tengo una variable que debe cumplir dos condiciones, y quiero establecerlas en la definición

Sé que puedo definir cualquiera de las condiciones con una variable individual, como en cualquiera de estos ejemplos

private Class<? extends A> variable; //or private A variable; //or private Class<? extends B> variable; //or private B variable;

Pero, ¿hay alguna manera de que la variable cumpla ambas condiciones?

Esperaba algo como esto

private Class<? extends A implements B> variable;

Pero no puedo encontrar ninguna forma de hacerlo sin el encasillado cuando necesito llamarlo o almacenar varias copias de él


Si bien Java no admite directamente tipos de intersección como A&B , dichos tipos aparecen en límites de parámetros de tipo y conversiones de captura. Podemos expresar A&B con una capa de abstracción.

public class ValueAB<T extends A&B> { public final T v; // constructor ... } public class ClassAB<T extends A&B> { public final Class<T> clazz; // constructor ... }

En lugar de A&B, Class<? extends A&B> A&B, Class<? extends A&B> , usamos envoltorios ValueAB, ClassAB

ClassAB<?> clazz = new ClassAB<>(Foo.class); ValueAB<?> value = new ValueAB<>(clazz.c.newInstance()); value.v.methodOfA(); value.v.methodOfB();

Esta solución requeriría un contenedor para cada combinación de As y Bs.

Otra solución es usar solo A como parámetro de tipo vinculado; B será proporcionado por un comodín vinculado. Esto probablemente sea mejor si necesita expresar múltiples tipos A&B1, A&B2, ... en el sitio de uso.

public class ValueA<T extends A> { public final T v; ... } public class ClassA<T extends A> { public final Class<T> c; ... } --- ClassA<? extends B> clazz = new ClassA<>(Foo.class); ValueA<? extends B> value = new ValueA<>(clazz.c.newInstance());

Si confunde cómo funciona el comodín en estos casos, vea mi artículo sobre comodines

Una tercera solución está libre de A o B en el sitio de declaración de los contenedores; el sitio de uso proporciona A y B.

public class Value<T extends S, S> { public final T v; ... } public class Clazz<T extends S, S> { public final Class<T> c; ... } --- Clazz<? extends A, B> clazz = new Clazz<>(Foo.class); Value<? extends A, B> value = new Value<>(clazz.c.newInstance());

Sin embargo, esto es probablemente demasiado confuso.