Post by Daniel Pittsi am java [sic] fresher,
i am a little bit confusion about runtime polymorphism.
Polymorphism is a compile-time phenomenon, too.
Post by Daniel Pittsand 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.
What is this "plz"? It is not an English word.
Post by Daniel PittsDowncasting gives you access to methods that are on the child class
Strictly speaking, it gives the compiler access.
Post by Daniel Pittsonly. It is often an indication of a bad design, but sometimes it is
unavoidable.
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'
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.
Post by Daniel PittsDowncasting 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