2016-06-10 2 views
-2

У меня есть DAO объекта, который я обычно продлить с именем класса сущностей, как так:Расширение общего класса реализатора

public class DAO<T> { 

    private final Class<T> clazz; 
    public DAO(Class<T> clazz { 
     this.clazz = clazz; 
    } 
} 

public class EntityDAO extends DAO<Entity> { 

    public EntityDAO() { 
     super(Entity.class); 
    } 
} 

Однако, у меня есть некоторые абстрактные объекты, которые я хотел бы создать абстрактный DAO который получает реализуется в конкретный класс позже:

public class DAO<T> { 

    private final Class<T> clazz; 
    public DAO(Class<T> clazz { 
     this.clazz = clazz; 
    } 
} 

public abstract class AbstractEntityDAO extends DAO<T extends AbstractEntity> { 

    public AbstractEntityDAO() { 
     super(AbstractEntity.class); 
    } 
} 

public abstract class EntityDAO extends AbstractEntityDAO <Entity> { 

    public EntityDAO() { 
     super(Entity.class); 
    } 
} 

Но это не работает, как AbstractEntityDAO жалуется неожиданная грань, и она не может решить Т. можно ли это сделать? И если да, то как это написано?

Это использование Java 1.7

ответ

1

Поместите общее определение типа на AbstractEntityDAO:

public abstract class AbstractEntityDAO<T extends AbstractEntity> extends DAO<T> { 
... 
} 

С текущего кода AbstractEntityDAO <Entity> должен сделать компилятор жалуется AbstractEntityDAO не имеющие общие параметры при.

Кроме того, ваш конструктор AbstractEntityDAO() должен принять параметр Class. Однако вам не нужно передавать класс как параметр вообще, если вы всегда используете экземпляры классов с конкретными типами. Используя отражение, класс может определить тип T, если существует конкретное определение, как в EntityDAO. Встроенные утилиты для отражения не обеспечивают простой способ сделать это, но, к счастью, вам нужен только небольшой дополнительный код для его получения. Посмотрите здесь: http://www.artima.com/weblogs/viewpost.jsp?thread=208860

Это в основном то, что мы делаем. Вот приблизительное краткое изложение нашего подхода:

abstract class BaseDAO<T> { 
    Class<?> entityClass; 

    BaseDAO() { 
    //this is based on the link I posted above but basically uses the actual concrete class 
    //(subclass determined by getClass()) to extract the generic types and 
    //since we only have one we get the first one from the returned list 
    entityClass = ReflectionHelper.getTypes(getClass(), BaseDAO.class).get(0); 
    } 

    public T getEntity(Object id) { 
    ... 
    } 
} 

abstract class TranslatableDAO<T extends TranslatableEntity> extends BaseDAO<T> { 
... 
} 

//Users are not translatable 
class UserDAO extends BaseDAO<User> { 
... 
} 

//Products are translatable, i.e. Product extends TranslatableEntity 
class ProductDAO extends TranslatableDAO<Product> { 
... 
} 
+0

Спасибо за это, я знал, что чего-то не хватает! – Draken

Смежные вопросы