Object Type Casting
MrJazsohanisharma

Object Type Casting


                                                        Object Type Casting

In programming, object type casting, also known as type conversion, is the process of converting an object from one data type to another. This is a common operation in many programming languages to handle situations where you need to use a variable or object of one data type in a context that expects a different data type. Type casting allows you to convert the value stored in the object while preserving the original data or performing some data manipulation if necessary.

 We can use parent reference to hold child object

eg-:

   Object o=new String("Ram");

we can use interface reference to hold implemented class object

eg-:

Runnable r=new Thread();



  • (compile time checking on the type of 'd' and 'C' must have some relation either child to parent or parent to child or same type) otherwise we will get compile time error saying inconvertible type found : d type required C type.
          eg-:  
                  Object o =new String("Ram");
                  StringBuffer sb=(StringBuffer) o;
          
         eg 2-:
                 String s=new String("Ram");
                 StringBuffer sb=(StringBuffer) s;
                   compile time error  inconvertible type 
                                                   found : java.lang.String 
                                                   required  java.lang.StringBuffer.


  • (compile time checking to 'C' must be either same or derived type of 'A' otherwise we will get compile time error saying incompartible types found 'C' required 'A')
          eg 1-:
            Object o=new String("ram");
             StringBuffer sb=(StringBuffer) o;

        eg 2-:
            Object o=new String("Sita");
            StringBuffer sb=(String) o;
            compile time error  incomputable type 
                                                   found : java.lang.String 
                                                   required  java.lang.StringBuffer.

  • Run time of object type of 'd' must be either same are derived type of 'C' otherwise we will get run type exception saying classCastException.
          eg 1-:
          Object o=new String("Shyam");
          StringBuffer sb=(StringBuffer) o;
   
          Run Time Exception -: ClassCastException : java.lang.String
                                                can't be type cast java.lang.StringBuffer





Base2 b=new Derive4("Hello");
  • Object o=(Base2)b;  //correct
  • Object o=(Base1)b; // inconvertible type
  • Object o=(Derive3)b; // run time exception
  • Base2 b1=(Base1)b; //inconvertible type
  • Base1 b1=(Derive4)b;//inconvertible type
  • Base1 b1=(Derive1)b;//inconvertible type


C c=new C();

B b=(B)c;
or 
B b=new C();
(A)((B)c)
or
A a=new C();





eg 1-:
class P{
    public static void m1(){
        System.out.println("Hi");
    }
}
class C extends P{
    public static void m2(){
        System.out.println("hello");
    }
}
public class Test{
    public static void main(String[] args){
   C c=new C();
   c.m1();                                //Hi
   c.m2();                              //Hello
   P p=new P();
     ((p)c).m1();                    ///Test.java:17: error: cannot find symbol
                                             ((p)c).m1();                    
                                              ^
                                              symbol:   class p
                                              location: class Test
   //OR
     P p=new C();
     p.m1();                          //Hi
   ((P)c).m2();                    ///Test.java:17: error: cannot find symbol
                                             ((P)c).m2();                    
                                              ^
                                              symbol:   method m2()
                                              location: class P
   //OR
  P p=new C();
  p.m2();                          ///Test.java:17: error: cannot find symbol
                                            p.m2();                    
                                              ^
                                              symbol:   method m2()
                                              location: variable p of type P
 }
}


Reason-:Parent reference can be used to hold child object, but by using the reference, we can't call child specific methods and can call only the method available in parent class.

eg 2-:

class P{
    public void m1(){
        System.out.println("A");
    }
}
class B extends P{
    public void m1(){
        System.out.println("B");
    }
    
}
class C extends B{
    public void m1(){
        System.out.println("C");
    }
}

public class Test{
    public static void main(String[] args){
   C c=new C();
   c.m1();                    //C
   ((B)c).m1();            //C
   ((P)((B)c)).m1();    //C
 }
}

Explanation of above code-:

This Java code demonstrates method overriding and method invocation in a class hierarchy involving three classes: `P`, `B`, and `C`. Let's break down the code step by step:

1. You have three classes: `P`, `B`, and `C`, where `B` extends `P`, and `C` extends `B`.


class P {
    public void m1() {
        System.out.println("A");
    }
}

class B extends P {
    public void m1() {
        System.out.println("B");
    }
}

class C extends B {
    public void m1() {
        System.out.println("C");
    }
}


- Class `P` has a method `m1()` that prints "A."
- Class `B` extends `P` and overrides the `m1()` method to print "B."
- Class `C` extends `B` and further overrides the `m1()` method to print "C."

2. In the `Test` class's `main` method:


public static void main(String[] args) {
    C c = new C();
    c.m1();                // Output: C


- You create an instance of `C` named `c` and call its `m1()` method. Since `c` is of type `C`, it invokes the `m1()` method from class `C`, and you see "C" printed.

3. Next, you perform explicit type casting:


    ((B)c).m1();            // Output: C


- Here, you explicitly cast `c` to type `B` using `((B)c)` and then call `m1()`. However, even with the cast, it still invokes the `m1()` method from class `C`. This is because the actual type of the object referenced by `c` is `C`, and Java's method dispatch mechanism is based on the actual runtime type of the object.

4. Further, you perform a nested type casting:


    ((P)((B)c)).m1();    // Output: C


- In this case, you first cast `c` to type `B` and then cast it again to type `P`. Despite the double casting, it still invokes the `m1()` method from class `C` because the actual object type is `C`.

In summary, this code demonstrates method overriding, where the method to be invoked is determined by the actual runtime type of the object rather than the reference type. Even when you perform explicit type casting, the method that gets executed is based on the object's actual type at runtime.

Note-:It is overriding, and method resolution is always based on run time object.


eg 3-:

class P{
    public static void m1(){
        System.out.println("A");
    }
}
class B extends P{
    public static void m1(){
        System.out.println("B");
    }
    
}
class C extends B{
    public static void m1(){
        System.out.println("C");
    }
}
class Test {
  public static void main (String[] args) {
C c=new C();
    c.m1();                        //C
    ((B)c).m1();                //B
    ((P)((B)c)).m1();        //A
  }
}

Explanation of above example-:
This code demonstrates method overriding and polymorphism in Java. Let's break down what each part of the code does:

1. **Class P**:
   - Class `P` is a parent class (superclass) that contains a static method `m1()`.
   - The `m1()` method in class `P` prints "A" when called.

2. **Class B**:
   - Class `B` extends class `P`, making it a subclass of `P`.
   - Class `B` also contains a static method `m1()`.
   - The `m1()` method in class `B` prints "B" when called.

3. **Class C**:
   - Class `C` extends class `B`, making it a subclass of `B`.
   - Class `C` also contains a static method `m1()`.
   - The `m1()` method in class `C` prints "C" when called.

4. **Class Test**:
   - Class `Test` contains the `main` method, which serves as the entry point for the program.
   - Inside the `main` method:
     - An instance `c` of class `C` is created.
     - `c.m1();` calls the `m1()` method on the `c` object, which is of type `C`. Therefore, it prints "C" to the console.
     - `((B)c).m1();` explicitly casts `c` to type `B` and then calls the `m1()` method on it. Since it's now considered as a `B` object, it prints "B" to the console.
     - `((P)((B)c)).m1();` first explicitly casts `c` to type `B` and then to type `P` and calls the `m1()` method on it. It is now considered as a `P` object, so it prints "A" to the console.

In summary, this code demonstrates how method overriding works in a class hierarchy. The type of the object determines which version of the method is called, and explicit casting can be used to change the perceived type of an object, affecting which method implementation is invoked.