2014-06-08 11 views
5

Эй, ребята, надеялись, что вы можете мне помочь.экземпляр объекта абстрактного класса с общим типом

В основном я создаю функцию с общим типом, и этот общий тип является абстрактным типом, который мне нужно создать. Этот код будет объяснить это более ясно:

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 


} 

В основном я хочу, чтобы обеспечить соблюдение «T расширяет AbstractRow но не абстрагироваться»

Я понимаю, что вы не можете создать экземпляр абстрактных классов, так что я хотел бы предложение об обходном пути или какой-либо другой метод, который позволил бы мне подражать поведению создания объекта родового типа. Заранее спасибо

+0

Вы не можете создать экземпляр абстрактного класса, если не реализовать все абстрактные методы. – user184994

+0

Я понимаю это. Мне нужно «обходное решение» или какая-то идея о том, как выполнить такую ​​работу по внедрению, когда мне нужно создать экземпляр объекта родового типа. –

+0

Ребята, с каких пор вы можете создавать типичные типы напрямую? – drewmoore

ответ

3

Ваша основная проблема заключается не в том, что вы работаете с абстрактным классом, и в этом случае предложения, размещенные в комментариях, будут полезны. Большая проблема заключается в том, что вы пытаетесь создать экземпляр типичного типа напрямую (читайте: new T()) - который, просто ставить, вы не можете сделать на Java из-за type erasure.

Тем не менее, всегда есть обходной путь:

/**@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 
} 

Использование:

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

Насколько я знаю, есть два способа сделать это:

  1. Добавить Class<T> type поле в ваш абстрактный общий класс и задайте его через конструктор (или другой метод). Затем вы можете вызвать type.newInstance(), чтобы создать объект.
  2. Создайте заводский интерфейс Factory<T> с помощью метода T create() и установите его как поле вашего абстрактного класса через конструктор (или другой метод). Создав конкретный экземпляр вашего универсального класса, вы также должны пройти конкретную реализацию этого завода.
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(); 
} 

Использование:

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

concrete.foo(); 
Смежные вопросы