import javax.swing.*;
public class Toast {
static Object[] objects = { new JButton(),
new String("Example"), new Object() };
public static void main(String[] args) {
System.out.println( new Count(objects) );
for (Object o : objects)
System.out.println(o);
}
}
class Count {
int b, s, o;
public Count(Object[] objects) {
for (int i=0; i<objects.length; i++)
count(objects[i]);
}
public void count(JButton x) { b++; }
public void count(String x) { s++; }
public void count(Object x) { o++; }
public String toString() {
return b + " : " + s + " : " + o + "\n";
}
}
上面是一段代码,在过去的考试试卷中以某种形式或其他形式出现,用于我即将进行的测试之一。这个问题的想法是衡量你是否完全理解多态,动态和静态铸造。 OO的基本思想。
我想说出我认为正确的内容,以及人们是否能够纠正我或添加非常感激的分数。
从我在上面的代码中看到的内容:
项目被上传到对象数组中的对象,因为java中的每个类在技术上都继承自对象类。这就是为什么当count运行时它会说有3个对象而不是1个Jbutton,1个字符串和1个对象。
当运行增强的for循环时,该对象类型的toString例如来自对象的字符串和内存地址的示例(不确定JButton将打印什么)。由于这是在运行时完成的,因此称为动态转换。
我看不到任何与上述代码相关的其他要点。
答案 0 :(得分:4)
静态强制转换和动态强制转换背后的想法与需要做出类型决策的时刻有关。如果需要由编译器进行,那么它是静态强制转换。如果编译器将决定推迟到运行时,那么它就是动态转换。
所以,你的第一次观察是不正确的。上调不解释计数。对象不会松散它们的类型,但编译器需要执行静态强制转换来决定调用哪个方法并选择count(Object)
。 java中没有动态调度,这意味着调用的方法总是在编译时决定。
你的第二次观察也是不正确的。正在使用的是多态。在Java中,始终为实例的类型调用方法,而不是为代码中的类型调用方法。此外,这里没有动态投射。编译器可以验证所有类型。只是方法调用总是virtual
,但这不是演员。
实际上在这个例子中,我没有看到一个动态投射的案例。编译器可以验证所有类型。您通常只会在向下投射时看到动态投射,并且没有这种情况。
答案 1 :(得分:2)
这是我要带走的东西:
执行赋值时,编译器会隐式重新编译。这包括在初始化期间分配数组元素。
选择方法重载时,编译器和JVM不会隐式向下转换。对象数组的静态类型为Object[]
,因此始终会调用count(Object)
方法。
JVM隐含地&#34;向下转换&#34; (在某种意义上)调用虚方法时。 println循环将始终调用实际对象实例的toString方法,而不是始终调用Object.toString。
答案 2 :(得分:2)
在Count()方法中,总是会调用count(object),因为所有对象都被上传到object。 为了防止你可以调用方法实例,然后向下转换对象并调用计数
public Count(Object[] objects) {
for (int i=0; i<objects.length; i++)
{
if(objects[i] instanceof JButton)
count((JButton) objects[i]);
else if(objects[i] instanceof String)
count((String) objects[i]);
else
count(objects[i]);
}
}