我有一個抽象類:
public abstract class AbstractPoint<PointType extends AbstractPoint<PointType>> {
public abstract double getX();
public abstract double getY();
public abstract double rho();
// Find the distance between two points
public final <T extends AbstractPoint<T>> double distance(T other) {
return vectorTo(other).rho();
}
// Find vector from one point to another.
public abstract <T extends AbstractPoint<T>> PointType vectorTo(T other);
// other methods ...
}
類OrthogonalPoint和PolarPoint擴展抽象類:
public class OrthogonalPoint extends AbstractPoint<OrthogonalPoint> {
private double x;
private double y;
public OrthogonalPoint(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() { return this.x; }
public double getY() { return this.y; }
public double rho() { return Math.sqrt(Math.pow(x, 2) Math.pow(y, 2)); }
public double theta() { return Math.atan2(this.y, this.x); }
public <T extends AbstractPoint<T>> OrthogonalPoint vectorTo(T other) {
return new OrthogonalPoint(other.getX() - this.x, other.getY() - this.y);
}
}
public class PolarPoint extends AbstractPoint<PolarPoint> {
private double rho;
private double theta;
public PolarPoint(double x, double y) {
this.rho = Math.sqrt(Math.pow(x, 2) Math.pow(y, 2));
this.theta = Math.atan2(y, x);
}
public double getX() { return this.rho() * Math.cos(this.theta()); }
public double getY() { return this.rho() * Math.sin(this.theta()); }
public double rho() { return this.rho; }
public double theta() { return this.theta; }
public <T extends AbstractPoint<T>> PolarPoint vectorTo(T other) {
return new PolarPoint(other.getX() - this.getX(), other.getY() - this.getY());
}
}
使用此代碼,無論點之間的距離是否相同(正交或極坐標),我都可以正確計算它們之間的距離。
現在我添加另一個名為的類Route:
public class Route {
private final List<? extends AbstractPoint<?>> points = new ArrayList<>();
// 'point' in 'this.points.add(point)' underlined red
public <T extends AbstractPoint<T>> void appendPoint(T point) { this.points.add(point); }
public <T extends AbstractPoint<T>> void removePoint(T point) { this.points.remove(point); }
// 'point' in '.distance(point)' underlined red
public double routeDistance() {
return this.points.stream().skip(1).mapToDouble(point ->
this.points.get(this.points.indexOf(point) - 1).distance(point)).sum();
}
}
路徑是有序數量的點,其長度定義為序列中點的距離之和。因此,如果一條路線由三個點(p1、p2 和 p3)組成,則該路線的距離為p1.distance(p2) p2.distance(p3)。
但是,Route我的代碼中的某些地方(查看 中的注釋)帶有紅色下劃線:
// in appendPoint function
Required type: capture of ? extends AbstractPoint<?>
Provided: T
// in routeDistance function
Required type: T
Provided: capture of ? extends AbstractPoint<?>
我希望能夠將任何型別的點添加到點串列和呼叫routeDistance函式來計算路線的長度。我的解決方案有什么問題 - 我應該如何更改我的泛型(在任何類中)?
uj5u.com熱心網友回復:
首先,請注意,您既要向points串列中添加資料,又要從串列中取出資料,因此不應使用extends或super。(另見:PECS)
private final List<AbstractPoint<?>> points = new ArrayList<>();
接下來,您將看到.distance(point)呼叫中有錯誤。這是因為沒有型別可以用來作為型別引數T的的distance方法,這也滿足約束T extends AbstractPoint<T>。請注意,型別point是AbstractPoint<?>,AbstractPoint<?>不能是T,因為AbstractPoint<?>不擴展AbstractPoint<AbstractPoint<?>>。看到問題了嗎?
據我所知,你寫的方式distance不允許你找到兩個AbstractPoints之間的距離。其中一個點必須是具體型別。
事實上,distance并且vectorTo實際上并不需要泛型引數。它可以只需要一個AbstractPoint<?>:
public final double distance(AbstractPoint<?> other) {
return vectorTo(other).rho();
}
public abstract PointType vectorTo(AbstractPoint<?> other);
現在,這可以讓你在傳遞AbstractPoint<?>到distance。
旁注:您當前的routeDistanceusing實作indexOf不是很有效,因為它對串列中的每個點都遍歷串列一次。您可以使用zip操作來執行此操作。使用zip鏈接答案中的方法:
return zip(points.stream(), points.stream().skip(1), AbstractPoint::distance)
.mapToDouble(x -> x).sum();
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/311170.html
