Results 1 to 14 of 14

Thread: Casting

  1. #1
    zzpprk is offline Member
    Join Date
    Aug 2009
    Posts
    26
    Rep Power
    0

    Default Casting

    Hi

    I am just looking at some code where the something strange is happening.

    I have the following.

    Class A
    Class B extends A
    Class C extends A
    Class D extends C

    Class A has a method called m() which is overloaded in B and C.

    The code I am looking at looks like the below where c is an instance of D.

    ((A)c).m()

    I would expect the method m() on class A to be called.
    What actually happens is that method m() on class C gets called.
    Does that mean that the cast of c from D to A is redundant?

    Does this type of casting occur at compile-time or at run-time?

    Regards

    Patrick

  2. #2
    Singing Boyo is offline Senior Member
    Join Date
    Mar 2009
    Posts
    552
    Rep Power
    6

    Default

    Casting an object does not change the object. Object c is still an object of class D, no matter how much casting you do. The method is overridden, not overloaded
    for example...
    Java Code:
    class Printer{
         public void print(){
              System.out.println("A Printer");
         }
    }
    class PrinterSub extends Printer{
         @Override//Annotation for OVERRIDEN methods
         public void print(){
              System.out.println("A Printer Subclass")
         }
         
    }
    public static void main(String[] args){
         Printer p = new PrinterSub();
         p.print();
    }
    The output is this:
    Java Code:
    A Printer Subclass
    This is because while the compiler regards p as a Printer, it is actually a PrinterSub.
    Your cast
    Java Code:
    ((A)c).m();
    makes the compiler regard c as an Object of type A for that line, but it is still an object of type D.

    As far as I know, there is no way to make it call A.m(). However, in C.m(), if you wrote this...
    Java Code:
    public void m(){
         super.m()
         //other code
    }
    C.m() would call A.m() as well as performing any additional code.

    Hope this helps,
    Singing Boyo

    EDIT: Exceptions are thrown at runtime as far as I know, so casting is probably performed at runtime
    Last edited by Singing Boyo; 08-09-2009 at 12:44 AM.
    If the above doesn't make sense to you, ignore it, but remember it - might be useful!
    And if you just randomly taught yourself to program, well... you're just like me!

  3. #3
    angryboy's Avatar
    angryboy is offline Senior Member
    Join Date
    Jan 2009
    Posts
    742
    Rep Power
    6

    Default

    In this case, casting is an extra step done at runtime.

    modding Boyo's code
    Java Code:
    public class Test {
      public static void main(String[] args){
           Printer p = new PrinterSub();
           ((Printer) p).print();
           ((PrinterSub) p).print();
           p.print();
      }
    }
    here's the bytecode:
    Java Code:
       8:   aload_1
       9:   invokevirtual   #4; //Method Printer.print:()V
    
       12:  aload_1
      [B] 13:  checkcast       #2; //class PrinterSub[/B]
       16:  invokevirtual   #5; //Method PrinterSub.print:()V
    
       19:  aload_1
       20:  invokevirtual   #4; //Method Printer.print:()V
    The jvm first looks for the method implementation in the method area, and takes the first one it finds. If its missing, it checks the superclass and so on. So casting is just an extra step here.
    USE CODE TAGS--> [CODE]...[/CODE]
    Get NotePad++ (free)

  4. #4
    Singing Boyo is offline Senior Member
    Join Date
    Mar 2009
    Posts
    552
    Rep Power
    6

    Default

    Another note...

    It would not be good if casting worked as you had expected, especially in the case of abstract classes/interfaces. To change my code a bit...
    Java Code:
    interface Printer{
         void print();
    }
    class PrinterSub implements Printer{
         @Override
         public void print(){
              System.out.println("Print Method");
         }
    }
    public static void main(String[] args){
         PrinterSub p = new PrinterSub();
         ((Printer)p).print(); //if it worked like you thought it did, BANG, the program would crash
    }
    The above code works, because it calls, as AB said, the first implementation it finds. If it worked as you had thought, there wouldn't be an implementation, and then what? There is a reason for how this works.

    Singing Boyo
    If the above doesn't make sense to you, ignore it, but remember it - might be useful!
    And if you just randomly taught yourself to program, well... you're just like me!

  5. #5
    zzpprk is offline Member
    Join Date
    Aug 2009
    Posts
    26
    Rep Power
    0

    Default

    Hi

    I agree 100% with the following.

    Java Code:
     
    ((A)c).m();
    makes the compiler regard c as an Object of type A for that line, but it is still an object of type D.
    My understanding is that the whole point of casting an object to its superclass is to call a method on that superclass. What would be the point of casting if that was not true?

    Regards

    Patrick

  6. #6
    RamyaSivakanth's Avatar
    RamyaSivakanth is offline Senior Member
    Join Date
    Apr 2009
    Location
    Chennai
    Posts
    836
    Rep Power
    6

    Default

    It is always advisable to use instanceOf and check before doing casting.
    Ramya:cool:

  7. #7
    Singing Boyo is offline Senior Member
    Join Date
    Mar 2009
    Posts
    552
    Rep Power
    6

    Default

    The thing is, casting an object to its superclass is only useful when reading objects from files when the 'real' class of the object has been changed, but the superclass has not been. This is to avoid incompatibilities between the old version and the new version, and part of why I base most of my classes on interfaces when I write large programs with regular changes.
    If the above doesn't make sense to you, ignore it, but remember it - might be useful!
    And if you just randomly taught yourself to program, well... you're just like me!

  8. #8
    dlorde is offline Senior Member
    Join Date
    Jun 2008
    Posts
    339
    Rep Power
    7

    Default

    You can only call a superclass method of the same name by casting if the method is declared static, so it's tied to the class type rather than the instance, which means it isn't overridden and polymorphism doesn't apply.

    If the method isn't static, polymorphism applies. This is why you can pass a subclass instance to a method taking a superclass type and still have it work correctly (polymorphically). Passing the subclass instance as a superclass argument is an implicit upcast.

  9. #9
    zzpprk is offline Member
    Join Date
    Aug 2009
    Posts
    26
    Rep Power
    0

    Default

    Quote Originally Posted by dlorde View Post
    You can only call a superclass method of the same name by casting if the method is declared static, so it's tied to the class type rather than the instance, which means it isn't overridden and polymorphism doesn't apply.

    If the method isn't static, polymorphism applies. This is why you can pass a subclass instance to a method taking a superclass type and still have it work correctly (polymorphically). Passing the subclass instance as a superclass argument is an implicit upcast.
    So what is the point of having something like that?
    Java Code:
    Class A
    {
        public void m()
        {
        }
    }
    
    Claass B extends A
    {
        public void m()
        {
        }
    }
    
    B c = new B();
    ((A)c).m();
    If I undertand correctly, the cast of c from B to A is redundant. Right?

  10. #10
    Singing Boyo is offline Senior Member
    Join Date
    Mar 2009
    Posts
    552
    Rep Power
    6

    Default

    Right. Casting to superclasses is not really useful. However, as I said, if you write an object to a file, and then change that object, if you cast it to a superclass that has NOT changed, it should still be compatible. e.g
    Java Code:
    class ASubClass extends ASuperClass
    void write(ASubClass ac){
         //write object to file
    }
    ASuperClass read(){
         //read and return object
    }
    The read method will work on any object written to a file, as long as ASuperClass is not changed. Any number of changes to ASubClass can occur. However, most changes to ASuperClass will make the files unreadable.
    If the above doesn't make sense to you, ignore it, but remember it - might be useful!
    And if you just randomly taught yourself to program, well... you're just like me!

  11. #11
    AlmostAGuru is offline Member
    Join Date
    Aug 2009
    Posts
    5
    Rep Power
    0

    Talking Write an application and try....thread closed

    Why dont you write an application and try..


    Thread closed....


    Jokers.....

  12. #12
    angryboy's Avatar
    angryboy is offline Senior Member
    Join Date
    Jan 2009
    Posts
    742
    Rep Power
    6

    Default

    re: post#5
    My understanding is that the whole point of casting an object to its superclass is to call a method on that superclass. What would be the point of casting if that was not true?
    If you can do that, then it wouldn't be oop design. You might as well program in C then.
    USE CODE TAGS--> [CODE]...[/CODE]
    Get NotePad++ (free)

  13. #13
    dlorde is offline Senior Member
    Join Date
    Jun 2008
    Posts
    339
    Rep Power
    7

    Default

    Quote Originally Posted by RamyaSivakanth View Post
    It is always advisable to use instanceOf and check before doing casting.
    Always? Not really...

  14. #14
    emceenugget is offline Senior Member
    Join Date
    Sep 2008
    Posts
    564
    Rep Power
    6

    Default

    There are two concepts to think about here, how Java actually works (irrefutable fact as it's just how it's coded for better or worse) and the concepts behind how Java works (arguable).

    How casting works in Java is that it doesn't change an object. An object contains anything that is non-static in the class, including methods. So, if you cast and call a method on an object, it will use the method defined for whatever instance it is (unless like someone else said, that method is static, but you shouldn't be calling a static method from an object anyways).

    The concept to think about here is what it conceptually means to subclass and override. D is a subclass of C, so it inherits properties of C. If C overrides a method of A, that means that it doesn't want to be treated like A in that aspect. Likewise, if D subclasses C, it also doesn't want to be treated like A in that way. If D does want to be treated like A and not C, then it should subclass A instead of C.

    Unless you want to make the point that casting an instance of C to A should be treated like A when

Similar Threads

  1. forced casting
    By hen1610 in forum New To Java
    Replies: 1
    Last Post: 03-06-2009, 05:49 PM
  2. help with type casting.
    By ramsrocker in forum Java Applets
    Replies: 15
    Last Post: 02-26-2009, 11:28 PM
  3. What does casting mean?
    By sev51 in forum New To Java
    Replies: 3
    Last Post: 01-27-2009, 04:31 PM
  4. casting help
    By soc86 in forum New To Java
    Replies: 4
    Last Post: 01-13-2009, 11:07 PM
  5. Casting
    By leebee in forum New To Java
    Replies: 5
    Last Post: 08-10-2007, 12:24 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •