我想保存 Arc
以及 Line
在一个数组列表中,然后得到两者的交集。问题是我该怎么投 i
以及 j
它的原始类。我知道 instanceof
但那将是最肮脏的方法。
public class Intersection {
public static boolean intersect(ArrayList<Curve> list1, ArrayList<Curve> list2) {
for (Curve i : list1) {
for (Curve j : list2) {
if (i.intersection(j).length > 0)
return true;
}
}
return false;
}
}
public abstract class Curve {
public Point[] intersection(Curve c) {
return new Point[] {};
}
}
public class Line extends Curve {
public Point[] intersection(Line l) {
// returns intersection Point of this and l
}
public Point[] intersection(Arc a) {
// returns intersection Point(s)
}
}
public class Arc extends Curve {
public Point[] intersection(Line l) {
// return intersection Point(s) of this and l
}
public Point[] intersection(Arc a) {
// returns intersection Point(s)
}
}
谢谢你的帮助!
7条答案
按热度按时间tvokkenx1#
第一个考虑:你需要转换(向上投射)
i
以及j
从Curve
至Arc
或者Line
?请看一下,例如:
在java中使用向上转换有什么必要?
如果你决定你真的需要向上投,不幸的是没有魔法蛋-你不能避免使用
instanceof
决定向上倾斜的班级。你可以把责任委托给另一个类,但基本上你不能回避它。
对不起的!
0aydgbwb2#
改变
Curve
到接口。保持平衡ArrayList<Curve>
同样的,取而代之的是,提取你的intersection
方法,并对其进行操作Curves
.你需要使用
instanceof
检查这里,但是由于使用了继承,您的设计会更干净一些。ejk8hzay3#
如果你不想使用
instanceof
另一种方法是使用合成来获取类型。下面的方法不会被使用instanceof
只使用首选Class.cast
操作:bwleehnv4#
我发现的一个解决方案是在
Curve
和一个if-else
子类中的链。但是我对这个解决方案并不满意。khbbv19g5#
因为每个子类都必须知道其他子类(例如,
Arc
必须意识到Line
类以实现Arc
以及Line
交叉口),使用instanceof
.在每个子类中,可以重写基类的
public Point[] intersection(Curve c)
方法并将实现分派给其中一个重载方法。例如:
这样你就不用改变你的生活了
public static boolean intersect(ArrayList<Curve> list1, ArrayList<Curve> list2)
方法。laximzn56#
处理这种用例有两种方法:
1.实施多次调度:
从制造开始
Curve
一个接口,并添加intersect
从而使它们成为合同的一部分。下一步,让intersection(Curve c)
方法将调用委托给适当的重载形式(a、 k.a.访客模式)你可以打电话给你的朋友
intersection
中的方法Intersection
类而不需要任何显式强制转换:附加:看看这个实现访问者模式的替代方法。
2.使直线和曲线符合同一界面(合同):
如果
Line
以及Arc
坚持Curve
,您的代码将不再需要intersect
方法。如果我们这么说Line
是一个Curve
和一个Arc
也是一个Curve
,这两个类的接口应与Curve
(我所说的接口是指它们支持的操作列表)。如果这些类与Curve
,这就是问题所在。本文介绍的方法Curve
应该是Line
以及Arc
班级。有几种策略可以消除子类在超类中不存在方法的需要:
如果与超类相比,子类需要额外的输入,则通过构造函数提供这些输入,而不是创建对这些输入进行操作的单独方法。
如果子类需要超类不支持的其他行为,请通过组合(读取策略模式)来支持此行为,而不是添加方法来支持其他行为。
一旦消除了在超类中不存在的子类中使用专用方法的需要,代码就会自动消除使用专用方法的需要
instanceof
或类型检查。这符合李斯科夫替代原理。yizd12fk7#
另一种选择是
isAssignableFrom
分类方法Class
. 下面是一个例子:这是我的javadoc
isAssignableFrom
方法,它是这么说的:确定此类对象表示的类或接口是否与指定的类参数表示的类或接口相同,或是其超类或超接口。如果是,则返回true;否则返回false。如果这个类对象表示一个基元类型,如果指定的类参数就是这个类对象,那么这个方法返回true;否则返回false。