开发者

What's the need to use Upcasting in java?

开发者 https://www.devze.com 2023-02-17 16:25 出处:网络
I\'ve gone through most of the papers in the net, but I\'m still not able to understand, why we have to use upcasting.

I've gone through most of the papers in the net, but I'm still not able to understand, why we have to use 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();
    }
}

You can consider this example for upcasting. What's the use of upcasting here? Both d and a giving the same output!


In most situations, an explicit upcast is entirely unnecessary and has no effect.

In your example, the explicit upcast

    Animal a = (Animal)d;

could be replaced with this:

    Animal a = d;    // implicit upcast

The purpose of an implicit upcast (for a Java object type) is to "forget" static type information so that an object with a specific type can be used in a situation that requires a more general type. This affects compile-time type checking and overload resolution, but not run-time behavior.

(For a primitive type, an upcast results in a conversion, and can in some cases result in loss of precision; e.g. long -> float.)


However, there are situations where the presence of an explicit upcast changes the meaning of the statement / expression.

One situation where it is necessary to use upcasting in Java is when you want to force a specific method overload to be used; e.g. suppose that we have overloaded methods:

public void doIt(Object o)...
public void doIt(String s)...

If I have a String and I want to call the first overload rather than the second, I have to do this:

String arg = ...

doIt((Object) arg);

A related case is:

doIt((Object) null);

where the code won't compile without the type cast. I'm not sure if this counts as an upcast (see JLS 5.1.13 last paragraph) but it should be mentioned anyway.

A second situation involves varadic parameters:

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.

A third situation is when performing operations on primitive numeric types; e.g.

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


What's the need to use Upcasting in java?

Not sure if you got the terminology right, but here is a quote to clarify:

upcasting
Doing a cast from a derived class to a more general base class.

And here's one scenario where it actually matters:

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"
    }
}

Another more subtle situation (related to access modifiers) is described here: Java Oddity: How an upcast can save the day


Upcasting has absolutely no meaning in your example (in fact I can't imagine any case where it has any) and should be avoided as it only confuses developers. Some IDEs (IntelliJ for sure) will issue a warning in this line and suggest removing upcasting).

EDIT: This code gives the same results because all object methods in Java are virtual, which means the target method is discovered by the actual type of the object at runtime rather than by reference type. Try making callme() static and see what happens.


Upcasting can be necessary when you have overloaded methods and do not want to call the specialized one, like aioobe wrote. (You could have assigned to a new variable of type A instead there.)

Another example where an upcast was necessary involved the ?: operator, but I don't remember it now. And sometimes you need upcasts in the case of varargs-methods:

public void doSomething(Object...  bla) {}

If we want to pass an Object[] array as a single parameter (not its objects as individual ones), we must write either

doSomething((Object)array);

or

doSomething(new Object[]{array});


Consider a scenario, Bank is a class that provides method to get the rate of interest. But, rate of interest may differ according to banks. For example, SBI, ICICI and AXIS banks are providing 8.4%, 7.3% and 9.7% rate of interest.

class Bank{  
    float getRateOfInterest(){return 0;}  
}

class SBI extends Bank{  
    float getRateOfInterest(){return 8.4f;}  
}

class ICICI extends Bank{  
    float getRateOfInterest(){return 7.3f;}  
}

class AXIS extends Bank{  
    float getRateOfInterest(){return 9.7f;}  
}  

class TestPolymorphism{  
    public static void main(String args[]){  
        Bank b;  
        b=new SBI();  
        System.out.println("SBI Rate of Interest: "+b.getRateOfInterest());  
        b=new ICICI();  
        System.out.println("ICICI Rate of Interest: "+b.getRateOfInterest());  
        b=new AXIS();  
        System.out.println("AXIS Rate of Interest: "+b.getRateOfInterest());  
    }  
}

Output:

SBI Rate of Interest: 8.4
ICICI Rate of Interest: 7.3
AXIS Rate of Interest: 9.7


Some answers:

  • Upcasting happens implicitly any time you pass a specific object to a method accepting a more generic object. In your example, when you pass a Dog to a method accepting an Animal, upcasting happens although you don't do it explicitly with parentheses.
  • As mentioned by others here, in method overloading scenarios where you have general and specific methods. In your example, imagine a method accepting a Dog, and another with the same name accepting an Animal. If for some reason you need to call the general version, you need to explicitly upcast your object.
  • Explicit upcasting can be used as a form of documentation; if at some point in your code you no longer need refer to a Dog as a Dog but continue treating it as an Animal, it may be a good idea to upcast to let other developers understand what's going on.


A Simple explaination of Upcasting is...

There are 2 classes one is parent class (Demo1) second is its subclass (Demo).

  1. If Method run1 does not have parameters then the output of method will be same. There is no use of Upcasting.

     class Demo1{
    
     void run1(){
     System.out.println("hello");  
     }
     }
    
    class Demo extends Demo1 {
    
    void run1(){
    System.out.println("hello1");  
    }
    
    public static void main(String args[]){
    
     Demo d = new Demo();
     d.run1();
    
     Demo1 d1 = new Demo();
     d1.run1();
    
      }
      }
    

    Output for d.run1(); and d1.run1(); will be same.

     output: hello1
    
    1. If we uses Parameterised overloading then the use of upcasting can be seen clearly. There is the sense for Upcasting.

        class Demo1{
      
        void run1(int a){
      
        System.out.println(a);  
        }
        }
      
       class Demo extends Demo1 {
      
        void run1(String b){
      
        System.out.println(b);  
        }
      
        public static void main(String args[]){
      
        Demo d = new Demo();
        d.run1("b");
      
        Demo1 d1 = new Demo();
        d1.run1(2);
      
      }
      }
      

Output for d.run1(); and d1.run1(); will be Different.

output: b
        2


Given that Java's objects methods are virtual by default, I do not see any use for upcasting at all.

Where have you seen tutorials reporting that upcasting was necessary? That is the first time I hear of it for Java. (Note that it has a meaning in C# or C++ - but it is usually a mark of bad design.)


When we upcast, we can only access the over-ridden methods but not all the methods of the child class.

Example code:

//class 1
public class Class1 {
  protected int value;

  public Class1(int value) {
    this.value = value;
  }

  protected int getValue() {
    return value;
  }
}

// class 2
public class Class2 extends Class1 {

  public Class2(int value) {
     super(value);
  }

  @Override
  public int getValue() {
    return super.getValue()+1;
  }

  public int getHundred() {
    return 100;
  }
}



//Main method
public class Main {
  public static void main(String args[]) {
    Class1 cls2 = new Class2(10);
    cls2.getValue();
    cls2.getHundred() // gives compile error
  }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消