Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.help > #2573

Re: difference between child class object and downcasting object

Newsgroups comp.lang.java.help
Date 2013-03-10 18:22 -0700
References <46d55c9b-7f17-4927-8b9f-b3acf8a0c407@googlegroups.com> <Lu4_s.33037$LX2.28117@newsfe31.iad>
Message-ID <4d91f4f4-b3ba-458b-a944-622a67473b79@googlegroups.com> (permalink)
Subject Re: difference between child class object and downcasting object
From Lew <lewbloch@gmail.com>

Show all headers | View raw


Daniel Pitts wrote:
> Sai varma wrote:
>> i am java [sic] fresher,
>> i am a little bit confusion about runtime polymorphism.

Polymorphism is a compile-time phenomenon, too.

>> and what is difference between child class object and downcasting object (i.e.both are 
>> access same methods then why we select downcasting).

An instance of a child class is just an object of the derived type.

A reference to such an object may be of that derived type or of any supertype, up to 'Object'.

So 
  Object foo = "A string";

defines an instance of the 'String' class (which is therefore also an instance of 'CharSequence', 
among other types), and identifies it to the compiler as an 'Object' instance.

That is a compiler view, that 'Object' type. At runtime the object still is what it is, and knows it.
So it is a 'String' no matter what the compiler does or does not know about it.

That is polymorphism. So when you call the 'Object#toString()' method on that 'foo' reference,

   foo.toString()

you are calling the instance's own version of that method, which is the 'String' method.

That is polymorphism.

But the compiler doesn't know that. It only knows that it's legal to call 'toString()' on an 'Object' 
reference.

But 'foo.substring(1)' would not be legal. Sure, the instance knows it has that method, but 'foo' is 
not a 'String' reference, so the compiler rejects the call.

Downcasting (in Java, "down" is from supertype to subtype, "up" is from subtype to supertype) tells 
the compiler to treat the instance as a subtype. The instance is not changed. Only the reference (i.e., 
the pointer) is changed.

  String bar = (String) foo;

Now the compiler lets you call 'bar.substring(1)'. 

However if you point 'foo' to something that is not a 'String', the compiler will let you get away with the 
downcast.

 foo = new File("foo");
 bar = (String) foo;
 System.out.println(bar.substring(1));

But the object that 'foo' points to doesn't have such a method, because it is not a 'String'.

So the cast will fail. The instance knows it's not really a 'String' and will force a 'ClassCastException' 
when the program executes the bad cast. Happy compiler, sad runtime.

>> plz give reply.

What is this "plz"? It is not an English word.
 
> Downcasting gives you access to methods that are on the child class 

Strictly speaking, it gives the compiler access.

> only. It is often an indication of a bad design, but sometimes it is 
> unavoidable.
> 
> For example, if you have:
> 
> class Parent {
>     public void foo() { System.out.println("parent foo"); }
> }
> 
> class Child extends Parent {
>     public void foo() { System.out.println("child foo"); }
>     public void bar() { System.out.println("child bar"); }
> }
> 
> Parent o = new Child();
> o.foo(); // prints 'child foo';
> o.bar(); // Compiler error, no such method on Parent.
> 
> ((Child)o).bar(); // prints 'child bar'
> 
> There is a danger when downcasting though:
> 
> Parent o = new Parent;
> 
> o.foo(); // prints 'parent foo'.
> (Child)o).bar(); // Not a compiler error, but a runtime error.

Now you can see how this works. 'o' points to an instance of 'Parent'. That instance "knows" 
that it is not a 'Child'. The compiler doesn't know this, and believes your downcast. The instance 
rejects this claim at runtime with an exception.

> Downcasting to a class that the object isn't will throw a 
> ClassCastException.

At runtime.

Happy compiler, sad runtime.

Incidentally, upcasting (called a "widening conversion" in Java) always works and is always safe, 
and in fact need not be stated:

  Child ch = new Child();
  Parent par = (Parent) ch; // unnecessary cast
  Parent prent = ch; // perfectly fine

Note that the 'par' and 'prent' variables cannot access methods that exist in 'Child' but 
not in 'Parent'.

It is a design principle in Java to push as much validation into the compiler phase as possible.

It is also a best practice to declare the widest (most supertypish) type for a variable that works 
for the code.

  List<Foo> foos = new ArrayList<>();

'foos' will actually point to an 'ArrayList', but for the code that uses it 'foo' is a 'List' at the compiler
level.

Study this:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

-- 
Lew

Back to comp.lang.java.help | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

difference between child class object and downcasting object Sai varma <saikondla@gmail.com> - 2013-03-07 05:59 -0800
  Re: difference between child class object and downcasting object Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-03-07 09:53 -0800
    Re: difference between child class object and downcasting object Lew <lewbloch@gmail.com> - 2013-03-10 18:22 -0700
  Re: difference between child class object and downcasting object Roedy Green <see_website@mindprod.com.invalid> - 2013-03-09 17:31 -0800
    Re: difference between child class object and downcasting object Roedy Green <see_website@mindprod.com.invalid> - 2013-03-11 22:35 -0700

csiph-web