I have and abstract class Image
which has two implementations: CTImage
and CRImage
. Specific type of Image is a part of Series (also abstract) with two implementations: CTSeries
and CRSeries
. When the object of specific Image is created it should create proper Series object, and add itself to proper implementation of Series
.
我有一个抽象类Image,它有两个实现:CTImage和CRImage。具体类型的Image是Series(也是抽象的)的一部分,有两个实现:CTSeries和CRSeries。在创建特定图像的对象时,应该创建适当的Series对象,并将其自身添加到Series的正确实现中。
Code I produced does not compile. Line `this.series.addImage(this); produces:
我生成的代码不能编译。行`this.Series.addImage(This);生成:
Required type:
capture of ? extends Image<S>
Provided:
Image<S>
The workaround is to add image to series in every implementation (commented lines) but that makes me reapeat myself. I just can't figure out what's the problem and how to fix it.
解决办法是在每个实现(注释行)中将图像添加到系列中,但这会让我收获颇丰。我就是想不出问题出在哪里,也不知道怎么解决。
import java.util.ArrayList;
import java.util.List;
abstract class Series<T extends Image<?>> {
protected List<T> images = new ArrayList<>();
public void addImage(T img) {
this.images.add(img);
}
public List<T> getImages() {
return images;
}
}
class CTSeries extends Series<CTImage> {
}
class CRSeries extends Series<CRImage> {
}
abstract class Image<S extends Series<? extends Image<S>>> {
protected S series;
public Image() {
this.series = createSeries();
this.series.addImage(this);
}
public S getSeries() {
return series;
}
protected abstract S createSeries();
}
class CTImage extends Image<CTSeries> {
public CTImage() {
// series.addImage(this);
}
@Override
protected CTSeries createSeries() {
return new CTSeries();
}
}
class CRImage extends Image<CRSeries> {
public CRImage() {
// series.addImage(this);
}
@Override
protected CRSeries createSeries() {
return new CRSeries();
}
}
更多回答
The relationship is weird. What's the point of an image adding itself to its series?
这段关系很奇怪。一个形象加入它的系列有什么意义?
@Sweeper In some parts of my app I have reference to image only and need to know which Series it is a part of. I can't see why this relationship is weird. When student attends school both sides have the knowledge about each other.
@Sweeper在我的应用程序的一些部分,我只引用了图像,需要知道它是哪个系列的一部分。我不明白为什么这段关系会很奇怪。当学生上学时,双方都有关于对方的知识。
But a student wouldn't create a school just to put themselves in there...
但一个学生不会仅仅为了把自己放在那里而创建一所学校。
What I expected was rather technical discussion, not the business side of my app.
我期待的是相当技术性的讨论,而不是我的应用程序的商业方面。
We're asking because there isn't a great, smooth solution to this and redesigning this arrangement may be the best strategy.
我们之所以问这个问题,是因为没有一个伟大的、平稳的解决方案,而重新设计这种安排可能是最好的策略。
优秀答案推荐
This can be done, but the types get a little complex, and there is still a small amount of necessary duplication.
这是可以做到的,但是类型变得有点复杂,并且仍然有少量必要的重复。
import java.util.ArrayList;
import java.util.List;
abstract class Series<S extends Series<S, I>, I extends Image<I, S>> {
protected List<I> images = new ArrayList<>();
public void addImage(I img) {
this.images.add(img);
}
public List<I> getImages() {
return images;
}
}
class CTSeries extends Series<CTSeries, CTImage> {
}
class CRSeries extends Series<CRSeries, CRImage> {
}
abstract class Image<I extends Image<I, S>, S extends Series<S, I>> {
protected S series;
public Image() {
this.series = createSeries();
this.series.addImage(thisImage());
}
protected abstract I thisImage();
public S getSeries() {
return series;
}
protected abstract S createSeries();
}
class CTImage extends Image<CTImage, CTSeries> {
public CTImage() {
}
@Override
public CTImage thisImage() {
return this;
}
@Override
protected CTSeries createSeries() {
return new CTSeries();
}
}
class CRImage extends Image<CRImage, CRSeries> {
public CRImage() {
}
@Override
public CRImage thisImage() {
return this;
}
@Override
protected CRSeries createSeries() {
return new CRSeries();
}
}
Other than the self-referential type parameters, the major change is the addition of the abstract thisImage
method, which is used instead of this
in the call to this.series.addImage
. This is because there is no way in Java to express "the type of this object". The concrete implementations all need to implement this method as return this;
. There's no way for it to be inherited from the Image
base class, as the compiler can't enforce that all possible subclasses will specify their own type as the value of I
.
除了自引用类型参数之外,主要的更改是添加了抽象的thisimage方法,而不是在对this.Series.addImage的调用中使用该方法。这是因为在Java中没有表示“该对象的类型”的方法。具体的实现都需要将该方法实现为返回This;。它不可能从Image基类继承,因为编译器不能强制所有可能的子类都将自己的类型指定为I的值。
更多回答
我是一名优秀的程序员,十分优秀!