Java - Remplacement du type de retour de l'interface étendue lorsque le type de retour utilise des génériques pour ses propres types de paramètres de méthode

j'ai trébuché sur une curiosité dans le java héritage, et je voulais vous demander de meilleures idées sur:

Assumer deux interfaces A et A1

Interface A1 s'étend Un

Interface Un a une méthode qui renvoie un type générique.

Le type générique serait comme GenericType<T>.

Une idée de base est maintenant de changer ce générique type de retour de
GenericType<Object> dans Une Interface en
GenericType<String> dans l'Interface A1

Bien semble facile au premier abord (mauvaises choses viendra plus tard)

Nous déclarer Une Interface comme

public interface InterfaceA {
  public GenericType<? extends Object> getAGenericType();  
}

et Interface A1 comme

public interface InterfaceA1 extends InterfaceA
{
  @Override
  public GenericType<String> getAGenericType();
}

Comme vous le voyez, nous sommes obligés d'écrire des GenericType<? extends Object> dans l'Interface elle-même pour permettre la remplaçant avec des génériques de base "sous-classes".
(En fait, le paramètre générique de la generictype est sous-classé pas le type générique lui-même)

Désormais assumer la GenericType a sa propre méthode de recherche comme:

public interface GenericType<D>
{
  public void doSomethingWith( D something );
}

Maintenant essayer d'instancier A1 fonctionne très bien.

Plutôt d'essayer d'instancier Un va sucer. Pour voir pourquoi chercher à partir de ce "utilisation de l'interface" de la classe:

public class LookAtTheInstance
{
  @SuppressWarnings("null")
  public static void method()
  {
    InterfaceA a = null;
    InterfaceA1 a1 = null;

    GenericType<String> aGenericType = a1.getAGenericType();

    GenericType<? extends Object> aGenericType2 = a.getAGenericType();
    Object something = null;
    aGenericType2.doSomethingWith( something );
  }
}

Vous demander: "Et maintenant?"

Il ne fonctionne pas sur les dernières lignes. En fait, le paramètre "quelque chose" n'est même pas de type "Objet", il est de Type "? s'étend de l'Objet". Si vous ne pouvez pas transmettre la déclaration de type "Objet". Vous ne pouvez pas passer quoi que ce soit.

Donc, vous vous retrouvez en déclarant nice interfaces qui, comme il s'avère, ne peut pas être instanciée droit.

Avez-vous des idées sur la façon de modéliser un tel cas d'utilisation, où les sous-classes devront remplacer le type de retour, tandis que le type de retour est un des génériques?

Ou comment feriez-vous autour d'un tel modèle?

Ou suis-je manque juste un simple point dans le générique de déclaration et mon exemple est possible de cette façon?

----------- (1) modifier grâce aux réponses -----------

Une très bonne idée de base est de rendre l'interface la plus abstraite! J'ai eu exactement la même idée première, mais... (ce qui a à venir)

Assumer ce faire:

Nous introduisons une nouvelle interface AGeneric

public interface InterfaceAGeneric<T>{
  public GenericType<T> getAGenericType();
}

Maintenant, nous allons avoir à étendre A et A1 à partir de cette nouvelle interface:

public interface InterfaceA extends InterfaceAGeneric<Object>{}
public interface InterfaceA1 extends InterfaceAGeneric<String>{}

Qui fonctionne très bien, malgré qu'elle rompt le chemin de l'héritage originel.

Si nous voulons A1 toujours être extensible à partir d'Un, nous devons changer de A1 à

public interface InterfaceA1 extends InterfaceA, InterfaceAGeneric<String>{}

et il y a un problème, c'est nouveau. Cela ne fonctionne pas, puisque nous étendre indirectement la même interface avec les différents types génériques. Ce n'est malheureusement pas autorisé.

Vous voyez le problème?

-

Et à point à un autre circonstance:

Si vous lancez la GenericType<? extends Object> à GenericType<Object> il fonctionne évidemment.
Exemple:

public class LookAtTheInstance
{
  public static void main( String[] args )
  {
    InterfaceA a = new InterfaceA()
    {
      @Override
      public GenericType<? extends Object> getAGenericType()
      {
        return new GenericType<Object>()
        {
          @Override
          public void doSomethingWith( Object something )
          {
            System.out.println( something );
          }
        };
      }
    };
    ;

    @SuppressWarnings("unchecked")
    GenericType<Object> aGenericType2 = (GenericType<Object>) a.getAGenericType();

    Object something = "test";
    aGenericType2.doSomethingWith( something );
  }  
}

Donc, il me semble que la résolution du type de paramètre de la méthode

public interface GenericType<D extends Object>
{
  public void doSomethingWith( D something );
}

est faux.

Si D est unifié avec "? s'étend de l'Objet" pourquoi le type de paramètre n'est pas forcé d'être "Objet"?

Pas plus de sens?

source d'informationauteur Omnaest | 2011-02-20