Может кто-нибудь объяснить, как параметры работают в иерархии Java?

#java #spring-boot #parameters #hierarchy

#java #spring-boot #параметры #иерархия

Вопрос:

Я новичок в наследовании Java, и мне трудно понять детали концепции. В моем проекте Springboot у меня изначально было 2 класса домена:

 public class Excerpt {
    private int excerptID;
    private String author;
    private String title;
    private String text;
    private String comments;
}

public class Tag {
    private int excerptID;
    private String description;
}
  

пакет DAO состоял из общего интерфейса DAO

 public interface DAO<T> {

    public void save(int id, String... params);
    public List<T> getAll();
    public List<T> getByTitle(String... params);
    public List<T> getByTag(String... params);
    public List<T> getByID(int excerptID);
    public int countAll();
    public void delete(int id);
}
  

и 2 реализации класса

 public class ExcerptDAO implements DAO<Excerpt> { ... }

public class TagDAO implements DAO<Tag> { ... }
  

Пока все хорошо. Но затем я решил добавить еще один класс домена Outline , который будет совместно Tag использовать таблицу базы данных с Excerpt

 public class Outline {
    private int outlineID;
    private String title;
    private String plot;
    private String comments;
    private String genre;
    private String resources;
}
  

Кроме того, методы DAO будут частично перекрываться, поэтому я добавил еще один уровень интерфейсов. Интерфейс umbrella DAO:

 public interface DAO<T> {

    public void save(int id, String... params);
    public List<T> getAll();
    public List<T> getByTitle(String... params);
    public List<T> getByTag(String... params);
    public List<T> getByID(int id);
    public int countAll();
    public void delete(int id);
}
  

ExcertpsDAO и расширяющие интерфейсы OutlinesDAO

 public interface ExcerptsDAO extends DAO<Excerpt>{
    public List<Excerpt> getByAuthor(String... params);
}

public interface OutlinesDAO extends DAO<Outline> {
    public List<Outline> getByGenre(String... params);
    public List<Outline> getByResource(String... params);
}
  

и я собираюсь внедрить их в классы, но не понимаю ошибку, которую я получаю:

 public class ExcerptDAO implements ExcerptsDAO<Excerpt> { ... }

The type ExcerptsDAO is not generic; it cannot be parameterized with arguments <Excerpt>
  

очевидно, это правильно

 public class ExcerptDAO implements ExcerptsDAO { ... }
  

но я не понимаю, почему параметр не принимается, когда он такой же, как в интерфейсе ExcerptsDAO. Почему это должно иметь значение, что интерфейс не является универсальным, если параметр один и тот же?

Комментарии:

1. Примечание: вам следует подумать о лучших именах или другой схеме именования для реализаций и интерфейсов. IMO ExcerptDAO и ExcerptsDAO слишком похожи и могут вызвать путаницу.

2. @Thomas, да, я знаю… Я хотел сделать это, как только решу практические вопросы

Ответ №1:

Если класс или интерфейс не принимает общие параметры, вам не разрешается добавлять их, точно так же, как вам не разрешается передавать параметры методу, который не принимает none . Итак ExcerptsDAO , имеет общие параметры и уже исправляет общий тип DAO , переданный to be Excerpt . Таким образом, вы не можете изменить параметр и, следовательно, его нельзя добавить.

Подводя итог: public class ExcerptDAO implements ExcerptsDAO { ... } отлично, поскольку ExcerptsDAO всегда будет иметь дело только с Excerpt экземплярами.

Если бы вы это сделали ExcerptsDAO<T extends Excerpt> implements DAO<T> , это сработало бы, но тогда вам пришлось бы всегда определять параметр общего типа ExcerptsDAO , поскольку он также может быть чем-то другим, чем Excerpt .

Ответ №2:

Вы пытались объявить общий параметр для ExcerptsDAO, но у него его нет. Но у DAO есть общий параметр (см. T в DAO<T> ). Вам нужны дженерики, только если вы хотите сделать класс, э, более универсальным.

Например, если вы хотите создать ExcerptsDAO не только для ваших выдержек, но и для других классов (что, конечно, не имеет смысла в данном случае), вы могли бы создать общий параметр.

 public interface ExcerptsDAO<T> extends DAO<T>{
    public List<T> getByAuthor(String... params);
}
  

Я не думаю, что в этом случае вам нужен универсальный.

Ответ №3:

Мой, вам нужно немного изменить вот так

 change : 

ExcerptsDAO extends DAO<Excerpt>
to
ExcerptsDAO<T> extends DAO<T>
  

И

 ExcerptsDAO implements ExcerptsDAO<Excerpt>
  

или вы также можете сделать это так

 public class ExcerptDAO implements ExcerptsDAO{}