R
R. Clayton
Why isn't downcasting more like upcasting?
I can directly assign a reference to a variable when the reference type
(dynamic type, actual type) is a descendant of the variable type (static type,
apparent type):
Parent p = new Child();
I can't directly assign a reference to a variable when the reference type
is a proper ancestor of the variable type; I need to use a cast (downcast):
Child c = (Child) p;
Why is the explicit downcast necessary? It doesn't seem to add any useful
information: p's dynamic type has to be compatible with c's static type, and
all that information can be gathered without the cast. I guess it allows
over-downcasting, as in (assuming a suitable assignment to p)
Child c = (GrandChild) p;
but that seems a rather obscure reason to force downcasting everywhere, and
does it matter anyway? There's only c's static and dynamic types; if p
contains a reference to a GrandGrandChild instance, the GrandChild-cast
information seems to disappear (e.g., c instanceof GrandGrandChild is true,
where it should be false if p's reference were treated as a GrandChild,
assuming the obvious inheritance hierarchy).
I can directly assign a reference to a variable when the reference type
(dynamic type, actual type) is a descendant of the variable type (static type,
apparent type):
Parent p = new Child();
I can't directly assign a reference to a variable when the reference type
is a proper ancestor of the variable type; I need to use a cast (downcast):
Child c = (Child) p;
Why is the explicit downcast necessary? It doesn't seem to add any useful
information: p's dynamic type has to be compatible with c's static type, and
all that information can be gathered without the cast. I guess it allows
over-downcasting, as in (assuming a suitable assignment to p)
Child c = (GrandChild) p;
but that seems a rather obscure reason to force downcasting everywhere, and
does it matter anyway? There's only c's static and dynamic types; if p
contains a reference to a GrandGrandChild instance, the GrandChild-cast
information seems to disappear (e.g., c instanceof GrandGrandChild is true,
where it should be false if p's reference were treated as a GrandChild,
assuming the obvious inheritance hierarchy).