有没有办法将对象强制转换为"最低"类?就我而言," Arc"和" Line"延伸"曲线"。我想将它们保存在ArrayList中,然后根据它们的类来对它们执行某些操作。这个例子输出"曲线","曲线"但我希望它是" arc"," line"。谢谢你的帮助!
public class Test4 {
public static void main(String[] args) {
ArrayList<Curve> curves = new ArrayList<>();
Arc arc = new Arc(new Point(0, 0, 0), 0, 0, 0);
Line line = new Line(new Point(0, 0, 0), new Point(1, 0, 0));
curves.add(arc);
curves.add(line);
for (Curve i : curves) {
test(i);
}
}
public static void test(Line l) {
System.out.println("line");
}
public static void test(Arc a) {
System.out.println("arc");
}
public static void test(Curve c) {
System.out.println("curve");
}
}
编辑:谢谢你的回答!它到目前为止工作,但我的问题有点复杂。我想要做的是找到两个几何对象的交点(所以线 - 弧线,线 - 线,线 - 圆等)。
public class Line{
//constructor and other methods
public Point[] intersection(Circle circle) {
//some code
}
public Point[] intersection(Line line) {
//some code
}
public Point[] intersection(LineSeg s) {
//some code
}
}
我想使用Curve
个对象访问这些方法,因此在abstract class Curve
中有一个方法intersection (Curve)
。当我调用此方法时,它返回一个空数组,因为它从Curve
类调用了该方法。如何告诉Java使用Arc,Line等类中的方法而不是Curve中的方法?
public abstract class Curve {
public Point[] intersection(Curve c) {
return new Point[] {};
}
}
答案 0 :(得分:3)
根据传递给方法的参数的静态类型,在编译期间解析方法重载,因此,当您传递Curve
类型的变量时,始终选择方法static void test(Curve c)
,无论如何变量i
引用的对象的运行时类型。
您可以使用实例方法替换静态test
方法,从而使用方法覆盖:
在Line class中:
public void test() {
System.out.println("line");
}
在Arc类中:
public void test() {
System.out.println("arc");
}
在曲线课程中:
public void test() {
System.out.println("curve");
}
将你的循环改为
for (Curve i : curves) {
i.test();
}
答案 1 :(得分:1)
这是你在那里最常见的设计错误。
正如@Eran所说,你应该将逻辑从全局处理程序移动到类实例中。
问题可以用另一种方式指定:
您将
Arc
和Line
之类的对象转换为更通用的形式 -Curve
然后尝试区分
Arc
和Line
个对象。
- 对于
Arc
输出消息,对象为Arc
- 对于
Line
输出消息,对象为Line
要区分对象类,必须使用Java机制:
执行其方法(对象的方法是确定对象类型的最佳方法)
使用instenaceof
运算符
因此,最好的专业方法是在每个类中实现方法test
:
public void test() {
System.out.println("Your type");
}
不建议使用instanceof
,因为它会产生错误,您可以编写如下代码:
public static void test(Curve c) {
if(c instanceof Arc) {
System.out.println("Arc");
return;
}
System.out.println("Something else");
}
在这种情况下,如果您添加新的类OtherGeometricalObject
,您可能会忘记更改test
的实现以添加行:
if(c instanceof OtherGeometricalObject) {
System.out.println("OtherGeometricalObject");
return;
}
这就是为什么instanceof
在大多数情况下是非常糟糕的交易,应该避免!
如果您想区分示例中的对象 (对一个类的对象执行某些操作,对其他类对象执行其他操作) 只需使用类方法!
这是为此目的而设计的机制!
我希望我的解释是丰富而有帮助的。)
答案 2 :(得分:1)
您希望为每个子类获取OOP行为,其行为取决于运行时类,但使用static
修饰符进行重载将不允许这样做。
根据声明的参数类型选择在编译时完成的方法。
正如Eran建议的那样,让每个子类定义其test()
方法并在其实例上调用该方法。
此外,您可以使用Object
方法执行所需的操作
方法toString()
用于返回表示对象的String。
您可以这样直接使用它:
for (Curve curve : curves) {
System.out.println(curve);
}
如果默认toString()
方法不适合您,您可以
在子类中覆盖它。
在Line class中:
public String toString() {
return "line";
}
在Arc类中:
public String toString() {
return "arc";
}
在曲线课程中:
public String toString() {
return "curve";
}