Searching a motivating example for upcasts

L

Lew

Andreas said:
If your point is specifically about local variables, as in the pattern
Map<X,Y> map = new HashMap<X,Y>();
then I'll step back, as for me, saving 4 key strokes (even 5 when
counting the Shift-key) would be enough, and about all the reason
to do so.

What do you mean, "about all the reason to do so"? There are a gazillion
reasons to do so.
 
L

Lew

Chris said:
Upcasting is an extraordinarily obscure operation in OOP; I'd recommend that
you just don't teach it at all. Or -- if you must -- then you teach it as a
Very Strange and Advanced operation which /ought/ to be a null-op always and
normally is, but just occasionally and in very odd situations, can affect the
semantics of an operation.

Nonsense. It's done all the time, and by best practice according to many of
the finest writers in the genre, such as Joshua Bloch in /Effective Java/.
 
L

Lew

I don't think that example is relevant.

I would expect Stefan to be perfectly aware of that type
of code.

It is very basic OOP.

The example he gave had an explicit upcast.

Since Java can do upcasts without an explicit cast operator, it is never
required and therefore always implicit unless for some reason you want to
document its existence. The effect of an implicit or explicit upcast is
precisely identical, so who cares which it is? To talk about one *is* to talk
about the other.
And whether that construct is useful is a lot more
questionable.

Since an upcast is always allowed, an explicit upcast is always redundant.

It doesn't make sense to ask about explicit upcast in isolation, because it is
the same as an implicit upcast in behavior. If there is any question about
the usefulness of an explicit upcast, I'd say no, it's not really ever useful
since other parts of the syntax make it clear if there's upcasting going on.
But it still is going on!
 
A

Arne Vajhøj

Nonsense. It's done all the time, and by best practice according to many
of the finest writers in the genre, such as Joshua Bloch in /Effective
Java/.

Assigning a ref to a sub type to a ref type of a super type
is done all the time.

But the explicit upcast used in Stefans example is not done
all the time.

Arne
 
R

Roedy Green

I don't think I've every actually used an upcast the way you show it,
but something like this is common and considered good practice:

Even if you upcast to Object, you still get the overridden methods
executed. A novice might think this gets you Object.toString for
example. You might want to clarify that in your essay.
--
Roedy Green Canadian Mind Products
http://mindprod.com
A short order cook is a master of multitasking. Every movement is
optimised from years of practice. Yet when a computer executes a
multitasking program, it approaches the task as if for the first time.
 
M

Mike Schilling

Lew said:
Since an upcast is always allowed, an explicit upcast is always redundant.

Not always.

class Logger
{
public log(Object o)
{
System.err.println(o);
}

public log (Collection c)
{
for (Object o : c)
{
log(o);
}
}
}

Logger logger;
List list;
logger.log((Object)list);
 
A

Arne Vajhøj

Not always.

class Logger
{
public log(Object o)
{
System.err.println(o);
}

public log (Collection c)
{
for (Object o : c)
{
log(o);
}
}
}

Logger logger;
List list;
logger.log((Object)list);

And that is actually a very good example of when an
explicit upcast is needed.

And it must be used sometimes in real life.

I would tend to avoid the construct if possible though.

Arne
 
L

Lew

What do you mean by "flexible" in quotes?

The point of generics declarations is similar to the point of, say, method
declarations or any other type declaration - you lock down the type by the
declaration. If you don't need a specific type, you lock down to a more
general type.

You should always lock down the type of your collection or other generic
class. Never use raw types. (Hacks that violate that rule notwithstanding.
They're hacks, and they're violations of that rule. It doesn't invalidate a
rule that there are exceptions. That's pre-emptive logic for all you
nitpickers who will rush to explain all the exceptions to the rule. Pointing
out exceptions is a form of acknowledgment of the rule, which is itself valid.)
I gave the example without a type parameter because Stefan was talking about
introducing students to polymorphism and inheritance. He wanted a "motivating
example" and there's lots of examples without the type parameters because
generics are relatively new in Java.

In new code, you should always use the type parameter. If you want
flexibility, use List<Object>.

Or, for cases where it's the right type declaration, 'List <?>' or 'List <?
extends DesiredSupertype>'.

The trick is to do a complete type analysis and capture the results in your
generics and interface declarations. Then the type declarations document your
analysis and the compiler enforces it.
 
A

Andreas Leitgeb

Lew said:
What do you mean, "about all the reason to do so"? There are a gazillion
reasons to do so.

That's why I "stepped back": to leave the explanation of those gazillions
of reasons to those who actually find them worth the time to post them...

Here's some scenarios (as a starting point for your gazillion of reasons):

- you find out that you *do* need the sub-class's extra methods, then
you have to change the declaration to use the subclass.

- you need the extra methods, but don't change the var's type, but
rather use a downcast ("I know it's a HashMap!") on the spot...
Bad Bad Bad ! (btw., the "you" isn't meant personally)
Of course you wouldn't ever do that, but a newbie indoctrinated
to always use the most abstract class for local vars, might do it.

- you don't need the subclass's extra methods, and have to change the
implementation (e.g. HashMap -> TreeMap). If you used Map before,
there is just one change, if you used HashMap before, then you also
change the variable to either Map or TreeMap now - the second change
is in the same line most of the times, or at least in the same
method, anyway. And the compiler will yell if you forget it.
So not that big a deal, really.

To me, any extra thinking effort invested into finding the top-most
class/interface to use for a local(!) variable is just like premature
optimization.

Anyway, with Collections it's much less likely to ever need a specific
implementation's method than e.g. with the *Stream-family. Thus, using
List and Map wouldn't count as "extra thinking effort" for me.
 
A

Arved Sandstrom

Peter said:
[...]
InputStream stream = new FileInputStream("foo");

This helps document in the code that, while the object is in fact a
FileInputStream, the code is intended only to use the functionality
available in InputStream.

I don't think that example is relevant.

I would expect Stefan to be perfectly aware of that type
of code.

It is very basic OOP.

The example he gave had an explicit upcast.

That does not mean that an explicit upcast is really what he's trying
to teach.

Fact is, an explicit upcast is required only for overload resolution,
which is not something he mentioned at all, and which is not really an
OOP concept at all. It doesn't seem likely to be relevant to a
programming class such as what Stefan may be teaching.

Of course, he is free to clarify. But it's not your place to discount
replies based on _your_ ASSumptions about what he might or might not
have meant.
[ SNIP ]

I sympathize with your line of argument, but in a 4:18 PM email on the 18th
Stefan made it clear that he's _not_ trying to teach an explicit upcase per
se; he's teaching what all of us (yourself and Arne included, most likely)
think he's teaching, which is the conversion to the supertype/base class.
Stefan makes it clear in that later email - something which was not obvious
in his OP - why he's using an explicit upcast (in his instructional flow) in
preference to assignment to a supertype.

AHS
 
J

Jim Janney

markspace said:
Thinking about this a bit, I don't like your example. I learned OOD
on my own, because OOD didn't really become popular until after I had
graduated.

One thing I had to overcome was the over abundance of examples based
on cars and other real world object (but especially cars). Objects in
OOD don't always correspond to real objects or even other user
requirements. Many objects are not objects per se, they are concepts.
The objects encapsulate some notion of design or functionality that
the designer needed to simplify his or her project, and are not really
"objects" in the way that the natural language understands that term.

This mirrors my own experience as a self-taught OO programmer. As it
happens, the first project I attempted in an OO language (C++) was a
program that communicated with an ATM. I wasted a lot of time trying to
write classes to model the physical parts of the ATM -- card reader,
cash dispenser, printer, etc. -- and getting nowhere. Eventually I
figured out that what I was really dealing with was more abstract
concepts like messages, protocols, sessions, and state machines. I
started writing classes to model those instead, and then things started
falling into place. But the examples in the books I'd read were not
helpful; if anything they actively led me astray.
 
E

Esmond Pitt

One thing I had to overcome was the over abundance of examples based on
cars and other real world object (but especially cars). Objects in OOD
don't always correspond to real objects or even other user requirements.

I would go further. I would say they practically never correspond to
real-world objects. Real-world objects like customers, suppliers,
employees, managers etc are generally modelled as flat collections of
attributes, bearing in mind that customers can also be suppliers,
employees can become managers, etc. OO is used primarily to express
*programming* concepts like collections, connections, projections,
injections, ... Even in an OO/hierarchical thing like LDAP the accepted
wisdom is *not* to mirror your organizational structure in the LDAP
treee, despite the fact that that is exactly what it was originally
designed to do.
 
A

Arne Vajhøj

[...]
InputStream stream = new FileInputStream("foo");

This helps document in the code that, while the object is in fact a
FileInputStream, the code is intended only to use the functionality
available in InputStream.

I don't think that example is relevant.

I would expect Stefan to be perfectly aware of that type
of code.

It is very basic OOP.

The example he gave had an explicit upcast.

That does not mean that an explicit upcast is really what he's trying to
teach.

Fact is, an explicit upcast is required only for overload resolution,
which is not something he mentioned at all, and which is not really an
OOP concept at all. It doesn't seem likely to be relevant to a
programming class such as what Stefan may be teaching.

Of course, he is free to clarify. But it's not your place to discount
replies based on _your_ ASSumptions about what he might or might not
have meant.

Hm. You don't want me to discount your answer based on my assumptions.
But you think it is fine for you to call Chris Uppals answer for
"close-minded statement" base on your assumptions????

Arne
 
A

Arne Vajhøj

They aren't assumptions. They are facts. His statement was trivial to
demonstrate as false.

Well - he did public state that your interpretation of
his reply was not what he was trying to communicate.

So how do you know that your interpretation was correct
and his later explanation was wrong?

Mind reading??

Arne
 
L

Lew

Chris said:
There seems to be a fairly large segment of the community of OO pundits who
regard the word "modelling" as a mistake.

Because it's misspelled?

Unless your program entity is the thing itself, it's a model of the thing, and
since no program manipulates actual domain entities but coded representations
of those entities, modeling the domain in a program is inevitable and ineluctable.
On the whole, I agree. Where OO brings /me/ benefit is that I can create
whatever abstractions I need to handle my target domain /without/ thereby being
forced to work at an unnatural distance from anything I can treat as "real".

I can create objects, and use the parts of my mind which are adapted to

You can create /models/ of domain objects using code objects.
thinking about physical "things", and especially to thinking about /people/, to
understand them. But the advantage comes precisely because the abstractions
the object represent are /not/ actual, physical, things. I.e. I can extend the
reach of my biologically hard-wired expertise in "people& things" into the
domain of abstractions (in general), and the target domain (in particular).

No models involved. Everthing is real in its own right.

Nothing but models involved. Nothing in your code is the real thing.
 
T

Tom McGlynn

Because it's misspelled?
Not at all. 'Modelling' is a perfectly acceptable spelling, perhaps
the preferred version outside the US. The US dictionaries give
'modeling' as the normal spelling with double-l acceptable but marked
as a UK variant. The British dictionaries make that the standard with
the single-l version marked as a mostly US variation. You shouldn't be
so parochial.

Regards,
Tom McGlynn
 
M

Mike Schilling

Tom McGlynn said:
Not at all. 'Modelling' is a perfectly acceptable spelling, perhaps
the preferred version outside the US. The US dictionaries give
'modeling' as the normal spelling with double-l acceptable but marked
as a UK variant. The British dictionaries make that the standard with
the single-l version marked as a mostly US variation. You shouldn't be
so parochial.

Or even "parochiall".
 
L

Lew

You shouldn't be such a namby-pamby.
Or even "parochiall".

I can't help it. I went to parochial school.

I should have said, "Because it was mispieled?"

Y'all don't do dry very well, do you? Too bad for you. Not only did you
comPLETEly miss out on the joke, you comPLETEly ignored the serious part of my
post, didn't you?

Again, too bad for you.
 
T

Tom Anderson

Because it's misspelled?

Unless your program entity is the thing itself, it's a model of the thing,
and since no program manipulates actual domain entities but coded
representations of those entities, modeling the domain in a program is
inevitable and ineluctable.


You can create /models/ of domain objects using code objects.


Nothing but models involved. Nothing in your code is the real thing.

I suspect that this is a matter of semantics. The point is that the
classes are not attempting to be little pictures of some real-world
entities like Managers, Trucks, Card Readers, etc. Whether you still
consider them models or not is, i think, not very interesting.

I lean towards siding with Chris, in that i believe there can be code
which is not a model. For instance, the last code i worked on before the
christmas holiday was reading messages out of a database, parsing them,
and sending the information in them to various consumers. The whole
business centres around the information in the messages; that information
does not exist anywhere outside my software (not once it's been read and
deleted from the database, anyway). If my message objects are models, what
are they models of?

tom
 
L

Lew

Tom said:
I suspect that this is a matter of semantics.

You say that as if it dismisses the point. It does not.

Since "semantics" means "meaning", it's rather important. If you don't mean
"modeling" when you say "modeling", that's rather significant.

Why do people say "matter of semantics" or "only semantics" as if semantics
were trivial? They're actually at the very core of successfully modeling your
problem or process in your code.
The point is that the classes
are not attempting to be little pictures of some real-world entities like
Managers, Trucks, Card Readers, etc. Whether you still consider them models or
not is, i think, not very interesting.

It may not be interesting to you, but as a response when someone says, "code
has no modeling in it" and "pundits think 'modeling' is a mistake", it's
directly to the point.
I lean towards siding with Chris, in that i believe there can be code which is
not a model. For instance, the last code i worked on before the christmas
holiday was reading messages out of a database, parsing them, and sending the
information in them to various consumers. The whole business centres around
the information in the messages; that information does not exist anywhere
outside my software (not once it's been read and deleted from the database,
anyway). If my message objects are models, what are they models of?

Your messages are models of thoughts to be communicated. To put it another
way, your messages are electronic models of words. If you could use carrier
pigeons to carry the messages as quickly and with the same throughput, it
would work just as well. It's not the messages themselves that count, it's
the information they convey. The messages model the information in a way that
can be transmitted through your system.

It's models and only models. People who assert that "modeling" is a mistake
are way off base.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top