2014-06-08 11 views
5

Hey ragazzi speravo che potessi aiutarmi.istanza oggetto di classe astratta con tipo generico

Fondamentalmente sto creando una funzione con un tipo generico e quel tipo generico è un tipo astratto che ho bisogno di istanziare. Questo codice spiegherà più chiaramente:

public <T extends AbstractRow> foo(){//no I did not actually name the function foo 
    ArrayList<T> arr=new ArrayList<T>(); 
    arr.add(new T(...)); //cant instantiate objects of abstract class 


} 

Fondamentalmente voglio rispettare "T estende AbstractRow ma non è astratta se stessa"

Mi rendo conto che non è possibile creare un'istanza classi astratte, così mi piacerebbe un suggerimento su una soluzione alternativa o qualche altro metodo che mi consenta di simulare il comportamento di creare un oggetto di tipo generico. Grazie in anticipo

+0

Non è possibile creare un'istanza di una classe astratta a meno che non si sceglie di implementare tutti i metodi astratti. – user184994

+0

Lo capisco. Ho bisogno di una soluzione alternativa o di un'idea su come realizzare un tale lavoro di implementazione in cui ho bisogno di istanziare un oggetto del tipo generico –

+0

Ragazzi, dal momento che è possibile creare direttamente i tipi generici? – drewmoore

risposta

3

Il tuo problema principale non è che si sta lavorando con una classe astratta - nel qual caso i suggerimenti pubblicati nei commenti sarebbero utili. Il problema più grande è che stai provando a creare un'istanza di un tipo generico direttamente (leggi: new T()) - che, semplicemente, non puoi fare in Java a causa di type erasure.

Detto questo, c'è sempre una soluzione:

/**@param clazz the subclass you want to instantiate */ 
public <T extends AbstractRow> foo(Class<T> clazz) { 
    ArrayList<T> arr = new ArrayList<T>(); 
    arr.add(clazz.newInstance); //instantiate new instance of given subclass 
} 

Usage:

abstract class Test1 {} 
class Test2 extends Test1{ } 

class Test<T> { 
    public static <T extends Test1> T foo(Class<T> clazz) { 
    T toReturn = null; 
    try{ toReturn = clazz.newInstance(); } catch (Exception e) { }; 
    return toReturn ; 
    } 

    public static void main(String[] args) { 
    Test1 t1 = t.foo(test2.class); 
    System.out.println(t1.getClass()); //prints "class pkgname.test2" 
    } 
} 
4

Per quanto ne so, ci sono due modi per farlo:

  1. Aggiungi un Class<T> type campo alla classe generica astratta e impostarlo tramite il costruttore (o un altro metodo). È quindi possibile richiamare type.newInstance() per creare l'oggetto.
  2. Creare un'interfaccia factory Factory<T> con un metodo T create() e impostarlo come campo sulla classe astratta tramite il costruttore (o un altro metodo). Dopo aver creato un'istanza concreta della classe generica, devi anche passare un'implementazione concreta di detta fabbrica.
import java.util.ArrayList; 
import java.util.List; 

public class Generic<T> { 
    private Factory<T> factory; 

    public Generic(Factory<T> factory) { 
     this.factory = factory; 
    } 

    public void foo() { 
     List<T> list = new ArrayList<>(); 

     list.add(factory.create()); 
    } 
} 

interface Factory<T> { 
    T create(); 
} 

Usage:

Generic<Bar> concrete = new Generic<>(new Factory<Bar>() { 
    @Override 
    public Bar create() { 
     return new Bar(); 
    } 
}); 

concrete.foo(); 
Problemi correlati