可以有人解释一下在Java层次结构中参数是如何工作的吗?

huangapple go评论70阅读模式
英文:

Can somebody explain how parameters work in java hierarchy?

问题

我对Java的继承机制还不太了解,很难理解这个概念的细节。在我的Springboot项目中,最初有两个领域类:

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);
}

以及两个类的实现:

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

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

到目前为止都还好。但后来我决定再添加另一个领域类Outline,它将与Excerpt共享Tag数据库表:

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

此外,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 id);
    public int countAll();
    public void delete(int id);
}

ExcerptsDAOOutlinesDAO继承了这些接口:

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> { ... }

错误信息是:类型ExcerptsDAO不是泛型的,无法使用参数<Excerpt>进行参数化。

显然,下面这种写法是正确的:

public class ExcerptDAO implements ExcerptsDAO { ... }

但我不明白为什么参数不被接受,尤其是接口中的参数与这里的参数是相同的。如果参数相同,为什么接口不是泛型会有影响呢?

英文:

I am new to java inheritance and have difficulties to understand the details of the concept. In my Springboot project I originally had 2 domain classes:

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;
}

the DAO package consisted of a generic DAO interface

public interface DAO&lt;T&gt; {

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

and 2 class implementations

public class ExcerptDAO implements DAO&lt;Excerpt&gt; { ... }

public class TagDAO implements DAO&lt;Tag&gt; { ... }

So far so good. But then I decided to add another domain class Outline which would be sharing Tag database table with Excerpt

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

Also the DAO methods would be partly overlapping, so I added another level of interfaces. The umbrella DAO interface:

public interface DAO&lt;T&gt; {

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

ExcertpsDAO and OutlinesDAO extending interfaces

public interface ExcerptsDAO extends DAO&lt;Excerpt&gt;{
	public List&lt;Excerpt&gt; getByAuthor(String... params);
}

public interface OutlinesDAO extends DAO&lt;Outline&gt; {
	public List&lt;Outline&gt; getByGenre(String... params);
	public List&lt;Outline&gt; getByResource(String... params);
}

and I am about to implement them into classes but do not understand an error I am getting:

public class ExcerptDAO implements ExcerptsDAO&lt;Excerpt&gt; { ... }

The type ExcerptsDAO is not generic; it cannot be parameterized with arguments &lt;Excerpt&gt;

evidently this is correct

public class ExcerptDAO implements ExcerptsDAO { ... }

but I do not understand why the parameter is not accepted when it is the same as in the ExcerptsDAO interface. Why should it matter that the interface is not generic if the parameter is the same?

答案1

得分: 2

如果一个类或接口没有使用泛型参数,你就不能添加任何参数,就像你不能向不接受参数的方法传递参数一样。所以 ExcerptsDAO 没有泛型参数,并且已经将传递给 DAO 的泛型类型修正为 Excerpt。因此,你不能改变这个参数,因此不允许添加参数。

总结一下:public class ExcerptDAO implements ExcerptsDAO { ... } 是完全可以的,因为 ExcerptsDAO 将始终仅处理 Excerpt 实例。

如果你这样做 ExcerptsDAO<T extends Excerpt> implements DAO<T>,它也可以工作,但是你必须始终为 ExcerptsDAO 定义一个泛型类型参数,因为它也可能是除了 Excerpt 之外的其他类型。

英文:

If a class or interface doesn't take generic parameters you're not allowed to add some, much like you're not allowed to pass parameters to a method that takes none. So ExcerptsDAO has_no_ generic parameters and already fixes the generic type passed to DAO to be Excerpt. So you can't change the parameter and thus it's not allowed to add one.

To summarize: public class ExcerptDAO implements ExcerptsDAO { ... } is perfectly fine since ExcerptsDAO will always only deal with Excerpt instances.

If you'd do ExcerptsDAO&lt;T extends Excerpt&gt; implements DAO&lt;T&gt; it would work but then you'd have to always define a generic type parameter for ExcerptsDAO since it could as well be something other than Excerpt.

答案2

得分: 1

你尝试为ExcerptsDAO声明了一个泛型参数,但它并没有。但是DAO有一个泛型参数(参见DAO&lt;T&gt;中的T)。只有在想要使一个类更加通用时才需要使用泛型。

例如,如果你想要创建一个ExcerptsDAO,不仅适用于你的摘要(Excerpts),还适用于其他类(当然在这种情况下没有意义),你可以创建一个泛型参数。

public interface ExcerptsDAO&lt;T&gt; extends DAO&lt;T&gt;{
    public List&lt;T&gt; getByAuthor(String... params);
}

我认为在这种情况下你并不需要使用泛型。

英文:

You tried to declare a generic parameter for ExcerptsDAO but it does not have any. But DAO has a generic parameter (see T in DAO&lt;T&gt;). You need generics only if you want to make a class, eh, more generic.

E.g. if you want to create a ExcerptsDAO not just your Excerpts but for other classes (which of course makes no sense in this case) you could create a generic parameter.

public interface ExcerptsDAO&lt;T&gt; extends DAO&lt;T&gt;{
    public List&lt;T&gt; getByAuthor(String... params);
}

I don't think you need a generic in this case.

答案3

得分: 0

你需要稍微修改一下,像这样:

更改:

ExcerptsDAO扩展DAO<Excerpt>

ExcerptsDAO<T>扩展DAO<T>

还有:

ExcerptsDAO实现ExcerptsDAO<Excerpt>
或者你也可以这样做:

public class ExcerptDAO实现ExcerptsDAO{}

英文:

My you need to change a bit like this

change : 

ExcerptsDAO extends DAO&lt;Excerpt&gt;
to
ExcerptsDAO&lt;T&gt; extends DAO&lt;T&gt;

And

ExcerptsDAO implements ExcerptsDAO&lt;Excerpt&gt;

or you can do this way as well

public class ExcerptDAO implements ExcerptsDAO{}

huangapple
  • 本文由 发表于 2020年9月30日 18:03:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/64135236.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定