我有两个简单的类:(Point
它有一个 x 和 y)和Point3D
(它extends Point
也有 az 参数)。我想覆盖 + 运算符,以便我可以添加两点。因为 + 运算符需要返回类,所以 Point 中 + 的方法签名与 Point3D 中 + 的签名不同,这在 Dart 中是不允许的。我已经通过一个界面试过了:
abstract class PointOperations<T extends Point> {
T operator +(T p);
}
并在 Point 和 Point3D 中实现这一点,如下所示:
class Point implements PointOperations<Point> {
final double x, y;
Point(this.x, this.y);
@override
Point operator +(Point p) => Point(x + p.x, y + p.y);
}
class Point3D extends Point implements PointOperations<Point3D>{
final double z;
Point3D(double x, double y, this.z) : super(x, y);
@override
Point3D operator +(Point3D p) => Point3D(x + p.x, y + p.y, z + p.z);
}
我收到编译错误The class 'Point3D' cannot implement both 'PointOperations<Point>' and 'PointOperations<Point3D>' because the type arguments are different.
我理解该错误,但不明白如何在不诉诸具有不同名称的方法(例如Point addPoint(Point p)
和Point3D addPoint3D(Point3D p)
)的情况下完成我想要的。
我可以使用命名构造函数使其工作:
Point.add(Point a, Point b) : x = a.x + b.x, y = a.y + b.y;
和
Point3D.add(Point3D a, Point3D b) : z = a.z + b.z, super(a.x + b.x, a.y + b.y);
但这并不优雅,当然也不是运算符重载。有没有办法做到这一点?
我想我想通了。在Point
我定义:
Point operator +(covariant Point p) => Point(x + p.x, y + p.y);
将参数定义为 acovariant
允许子类在Point3D
没有冲突的情况下使用该参数。在Point3D
我定义:
@override
Point3D operator +(Point3D p) => Point3D(x + p.x, y + p.y, z + p.z);
返回类型有效,因为它是Point
.
请注意,可以使用以下替代方法:
@override
Point3D operator +(Point p) => Point3D(x + p.x, y + p.y, z + (p as Point3D).z);
where 需要您强制转换Point p
to access z
,但是如果您想将 a 添加Point
到 a Point3D
(这将需要额外的类型检查并且不是我正在寻找的,但可以想象这样做并设置z
为 0 如果p
是),这可能很有用一个Point
而不是Point3D
)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句