在Java中使用Upcasting有什么需要?
问题内容:
我已经浏览了网络上的大多数论文,但是我仍然无法理解为什么我们必须使用向上转换。
class Animal
{
public void callme()
{
System.out.println("In callme of Animal");
}
}
class Dog extends Animal
{
public void callme()
{
System.out.println("In callme of Dog");
}
public void callme2()
{
System.out.println("In callme2 of Dog");
}
}
public class UseAnimlas
{
public static void main (String [] args)
{
Dog d = new Dog();
Animal a = (Animal)d;
d.callme();
a.callme();
((Dog) a).callme2();
}
}
您可以考虑使用此示例进行上播。这里的向上转换有什么用?两者d
并a
给出相同的输出!
问题答案:
在大多数情况下,完全没有必要进行明确的插播,也没有任何效果。
在您的示例中,显式上行
Animal a = (Animal)d;
可以替换为:
Animal a = d; // implicit upcast
隐式转换(用于Java对象类型)的目的是“忘记”静态类型信息,以便具有特定类型的对象可以在需要更通用类型的情况下使用。这会影响编译时类型检查和重载解析,但不会影响运行时行为。
(对于原始类型,向上转换会导致转换,并且在某些情况下会导致精度损失;例如long
-> float
。)
但是,在某些情况下,显式上载的存在会更改语句/表达式的含义。
在Java中有必要使用向上转换的一种情况是,您想强制使用特定的方法替代。例如,假设我们有重载的方法:
public void doIt(Object o)...
public void doIt(String s)...
如果我有一个String,并且想调用第一个重载而不是第二个重载,则必须这样做:
String arg = ...
doIt((Object) arg);
一个相关的案例是:
doIt((Object) null);
没有类型转换,代码将无法编译。(我不确定这是否算是高潮,但还是这样。)
第二种情况涉及可变参数:
public void doIt(Object... args)...
Object[] foo = ...
doIt(foo); // passes foo as the argument array
doIt((Object) foo); // passes new Object[]{foo} as the argument array.
第三种情况是在对原始数值类型执行操作时。例如
int i1 = ...
int i2 = ...
long res = i1 + i2; // 32 bit signed arithmetic ... might overflow
long res2 = ((long) i1) + i2; // 64 bit signed arithmetic ... won't overflow