Re: Searching a motivating example for upcasts
On 18.12.2010 17:49, Stefan Ram wrote:
For my teaching, I finally found a path to OOP in Java that
pleases me, but it involves teaching the use of the upcast
early. We can write, for example:
( Object )string
and what this does is: It limits the possible uses of the
expression. While we once were able to call
string.length(),
we are now not anymore able to call
( ( Object )string ).length()
. And to a beginner such a limitation must seem like a
failure. He should ask himself: =BBWhy would anyone sane
in his mind limit his possible options voluntarily?=AB
The OOP answer is that this is a intermediate step on the
way to a method:
example( final Object object ){ ... }
that is so general that it can be called as
example( string )
and also as
example( integer )
as well. The compiler will check that we do not call any
methods too specific to any subclass of Object in the
declaration of =BBexample=AB. In this sense the use of
an upcast is to make the compiler check that certain
methods are not called.
However, I can not yet give this explanation, since in my
teaching upcasts are introduced earlier than parameters of
reference type.
.---------------------------------------------------------.
| So I am looking for any real world examples where it is |
| advantageous to limit voluntarily the possibilities of |
| some object in order to make sure that one uses a |
| general procedure on it. |
'---------------------------------------------------------'
Or else, any motivating example or explanation for the
use of an upcast that does not involve any other OOP
features of Java than the invocation of nonstatic methods.
I just want to convey in a credible manner that it sometimes
helps to restrict the set of possible method calls to people
who at this moment do not know anything about Java OOP
features except for calls of object methods via an object.
I never used an explicit "upcast" like you showed. If at all it happens =
because I assign a reference to a super class type reference (this
includes method parameters). This seems the most natural thing: you
write a method and declare the minimal necessary type to perform the
task and it will happily accept sub class arguments. So this is not a
use case of limiting something but rather reducing requirements and thus =
extending (!) usability of a method.
public static boolean checkSize(Collection<?> c) {
int count = 0;
for (Object x : c) {
++count;
}
return count == c.size();
}
Now you can call checkSize() with an ArrayList, HashSet instance etc.
For teaching I'd probably do something which uses one instance method of =
Object:
public static generalHash(Object x) {
return x == null ? 0 : x.hashCode();
}
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/