在java中使用Upcasting有什么需要?

Aru*_*ung 15 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以将此示例视为向上转换.在这里使用向上转换有什么用?两者da给出相同的输出!

Ste*_*n C 23

在大多数情况下,明确的上传完全没有必要,并且没有任何效果.

在您的示例中,显式向上转发

    Animal a = (Animal)d;
Run Code Online (Sandbox Code Playgroud)

可以用这个代替:

    Animal a = d;    // implicit upcast
Run Code Online (Sandbox Code Playgroud)

隐式upcast(对于Java对象类型)的目的是"忘记"静态类型信息,以便具有特定类型的对象可以在需要更通用类型的情况下使用.这会影响编译时类型检查和重载解析,但不会影响运行时行为.

(对于基本类型,upcast会导致转换,并且在某些情况下会导致精度损失;例如long- > float.)


但是,在某些情况下,显式upcast的存在会改变语句/表达式的含义.

需要在Java中使用upcasting的一种情况是当你想强制使用特定的方法覆盖时; 例如,假设我们有重载方法:

public void doIt(Object o)...
public void doIt(String s)...
Run Code Online (Sandbox Code Playgroud)

如果我有一个字符串,我想调用第一个重载而不是第二个,我必须这样做:

String arg = ...

doIt((Object) arg);
Run Code Online (Sandbox Code Playgroud)

一个相关的案例是:

doIt((Object) null);
Run Code Online (Sandbox Code Playgroud)

如果没有类型转换,代码将无法编译.(我不确定这是否算作上传,但无论如何它都在这里.)

第二种情况涉及varadic参数:

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.
Run Code Online (Sandbox Code Playgroud)

第三种情况是对原始数字类型执行操作; 例如

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
Run Code Online (Sandbox Code Playgroud)


aio*_*obe 10

在java中使用Upcasting有什么需要?

不确定你是否有正确的术语,但这里是一个澄清的引用:

向上转换
从派生类转换为更通用的基类.

这是一个实际问题的场景:

class A {
}

class B extends A {
}

public class Test {

    static void method(A a) {
        System.out.println("Method A");
    }

    static void method(B b) {
        System.out.println("Method B");
    }

    public static void main(String[] args) {
        B b = new B();
        method(b);                      // "Method B"

        // upcasting a B into an A:
        method((A) b);                  // "Method A"
    }
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*icz 5

在您的示例中,Upcasting绝对没有意义(事实上,我无法想象在任何情况下都有它),应该避免这样做,因为它只会使开发人员感到困惑。某些IDE(肯定是IntelliJ)会在此行中发出警告,并建议删除向上转换。

编辑:此代码给出相同的结果,因为Java中的所有对象方法都是虚拟的,这意味着目标方法是在运行时通过对象的实际类型而不是引用类型发现的。尝试使callme()静态,看看会发生什么。


Paŭ*_*ann 5

当你有重载方法并且不想调用专用方法时,可能需要向上转换,就像aioobe写的那样.(你可以在那里分配一个新的类型变量A.)

需要向上移动的另一个例子涉及?:操作员,但我现在不记得了.有时你需要在varargs-methods的情况下进行upcast:

public void doSomething(Object...  bla) {}
Run Code Online (Sandbox Code Playgroud)

如果我们想要传递Object[] array一个单独的参数(而不是它的对象作为单个参数),我们必须写一个

doSomething((Object)array);
Run Code Online (Sandbox Code Playgroud)

要么

doSomething(new Object[]{array});
Run Code Online (Sandbox Code Playgroud)