How to check if object is an instanceof a class, but not a sub-class?

A

Arne Vajhøj

What are you supposed to do if the appropriate level of abstraction
varies at run time?

I'll sometimes think "There's a peacock" or "There's a mallard duck",
but at other times "That's a very elegant brown bird". The level of
abstraction changes depending on the information I have about the bird.

Sometimes I have enough information to classify the bird by species,
sometimes by general type - I can tell the difference between a duck and
a vulture, without necessarily knowing the exact species - and sometimes
just by "bird" plus description.

But I believe that is more:

Bird b = ObservationFactory.seeAt(point);

than:

Bird b = new Bird(attr);

:)

Arne
 
A

Arne Vajhøj

Eric said:
On 6/26/2010 9:40 AM, Patricia Shanahan wrote:
[ SNIP ]
It seems to me that the choice of taxonomy is driven not by the
nature of the things "out there" in the world, but by their nature
in the program's model of the world. One program may find it useful
to distinguish between Thrush and Swallow. Another may need to go
further and distinguish Goose from Gander. Still another may just
use Bird, with a single parameter describing how much damage it does
when sucked into an aircraft engine. The features chosen for modeling
have more to do with the nature of the model than with the true nature
(whatever *that* is) of the thing modeled.

This is all true. But I'll wager that rarely - maybe even very rarely -
do you really benefit from trying to capture any of those distinguishing
features in an inheritance tree. Not just for this Bird example but for
a whole bunch of other examples.

My main point would be that a real-world taxonomy is not often modelled
best with a programming taxonomy implemented with traditional
inheritance. For a variety of reasons.

I don't think anyone is arguing against the two cases:
1) just having a Bird class
2) having an abstract Bird class and concrete subclasses
I think the argument is against having:
3) instances of Bird and instances of subclasses of Bird in the
same app

I would even say that #3 is sometimes practical, but it is not
good OOP.

Arne
 
M

Martin Gregorie

I would even say that #3 is sometimes practical, but it is not good OOP.
Then the geometric drawing example that's often seen in teach-yourself
Java and C++ books where Point is defines as a concrete base class and
then extended extended to form Circle, Ellipse, Rectangle, Triangle, ....
classes shouldn't really be used because its bad OOP?

However, I don't think Bird is a particularly good example simply because
almost all case I can think of where I'd might be interested in using it
would compare birds across species in ways that would require the same
attributes in all instances, so extensions simply wouldn't arise,
particularly if the attributes flightless, aquaticSpecies and (possibly)
diver were used.
 
S

Screamin Lord Byron

I don't think anyone is arguing against the two cases:
1) just having a Bird class
2) having an abstract Bird class and concrete subclasses
I think the argument is against having:
3) instances of Bird and instances of subclasses of Bird in the
same app
Exactly.


I would even say that #3 is sometimes practical, but it is not
good OOP.


I'll have to agree with that.

The bottom line is what Mike Schilling said in the beginning: if you
need to do an exact class-check, then you should probably think again
about your design.
 
S

Screamin Lord Byron

Then the geometric drawing example that's often seen in teach-yourself
Java and C++ books where Point is defines as a concrete base class and
then extended extended to form Circle, Ellipse, Rectangle, Triangle, ....
classes shouldn't really be used because its bad OOP?

What book is that? There is a huge difference between IS-A and HAS-A
relationship.

Circle is not a point, therefore it cannot extend Point. Circle HAS-A
point. Circle IS-A geometric shape. Class GeometricShape should, of
course, be made abstract.
 
A

Arne Vajhøj

Then the geometric drawing example that's often seen in teach-yourself
Java and C++ books where Point is defines as a concrete base class and
then extended extended to form Circle, Ellipse, Rectangle, Triangle, ....
classes shouldn't really be used because its bad OOP?

I assume that you mean Figure and not Point as base class.

Yes - I don't think Figure should be concrete.

And in general those figure examples often lead to problems like
the wellknown Rectangle versus Square problem.
However, I don't think Bird is a particularly good example simply because
almost all case I can think of where I'd might be interested in using it
would compare birds across species in ways that would require the same
attributes in all instances, so extensions simply wouldn't arise,
particularly if the attributes flightless, aquaticSpecies and (possibly)
diver were used.

A lot depends on the context.

Arne
 
A

Arved Sandstrom

Arne said:
Eric said:
On 6/26/2010 9:40 AM, Patricia Shanahan wrote:
[ SNIP ]
Sometimes I have enough information to classify the bird by species,
sometimes by general type - I can tell the difference between a duck
and
a vulture, without necessarily knowing the exact species - and
sometimes
just by "bird" plus description.

It seems to me that the choice of taxonomy is driven not by the
nature of the things "out there" in the world, but by their nature
in the program's model of the world. One program may find it useful
to distinguish between Thrush and Swallow. Another may need to go
further and distinguish Goose from Gander. Still another may just
use Bird, with a single parameter describing how much damage it does
when sucked into an aircraft engine. The features chosen for modeling
have more to do with the nature of the model than with the true nature
(whatever *that* is) of the thing modeled.

This is all true. But I'll wager that rarely - maybe even very rarely -
do you really benefit from trying to capture any of those distinguishing
features in an inheritance tree. Not just for this Bird example but for
a whole bunch of other examples.

My main point would be that a real-world taxonomy is not often modelled
best with a programming taxonomy implemented with traditional
inheritance. For a variety of reasons.

I don't think anyone is arguing against the two cases:
1) just having a Bird class
2) having an abstract Bird class and concrete subclasses
I think the argument is against having:
3) instances of Bird and instances of subclasses of Bird in the
same app

I would even say that #3 is sometimes practical, but it is not
good OOP.

Arne

Agreed. In this particular case, let's say where sometimes you only know
it's a bird without too much extra information, sometimes you're
positive it's a duck, and sometimes you know for a fact it's a male
hooded merganser, and you're interested in recording all observed birds
with as much information as is possible, I'd stick with #1.

My wider argument, made in the post you answered and also in another, is
that I'd rarely consider in this or other situations going with #2
unless the inheritance tree was only one level deep. But even more often
I'd stick with interfaces and composition/aggregation to achieve what I
want.

AHS
 
M

Martin Gregorie

I assume that you mean Figure and not Point as base class.
Unfortunately not:

"Data Abstraction and Object-Oriented Programming in C++" by Gorlen,Orlow
and Plexico uses Point as components within Line and Circle classes
though without explicit inheritance: I don't read C++ well enough to
understand much more than this, but I think there's no inheritance and no
abstract base class.

However, Ivor Horton's "Beginning Java" does better: I misremembered what
it said. It uses a utility Point class but bases its shapes on an
abstract Element base class which only has a colour attribute.
A lot depends on the context.
True enough, though a Bird with as species attribute would be very useful
since it could be used for anything from building an experimental results
database for a study of avian flight performance to building a cladistic
species descent tree. Doing either would be harder if Bird was merely an
abstract base class.
 
M

Martin Gregorie

Unfortunately not:

"Data Abstraction and Object-Oriented Programming in C++" by
Gorlen,Orlow and Plexico uses Point as components within Line and Circle
classes though without explicit inheritance: I don't read C++ well
enough to understand much more than this, but I think there's no
inheritance and no abstract base class.

However, Ivor Horton's "Beginning Java" does better: I misremembered
what it said. It uses a utility Point class but bases its shapes on an
abstract Element base class which only has a colour attribute.

True enough, though a Bird with as species attribute would be very
useful since it could be used for anything from building an experimental
results database for a study of avian flight performance to building a
cladistic species descent tree. Doing either would be harder if Bird was
merely an abstract base class.
Is my first example (the flight performance measurements database) a case
for using the Bird object with factories, such as a RacingPigeon factory
or a HerringGull factory, rather than subclasses?
 
S

Screamin Lord Byron

Unfortunately not:

"Data Abstraction and Object-Oriented Programming in C++" by Gorlen,Orlow
and Plexico uses Point as components within Line and Circle classes
though without explicit inheritance: I don't read C++ well enough to
understand much more than this, but I think there's no inheritance and no
abstract base class.

That's right. Point is an attribute of Line and Circle. That's
composition, not inheritance. I believe this discussion was about
inheritance, so I must admit that I fail to see your point.
 
C

ClassCastException

And in general those figure examples often lead to problems like the
wellknown Rectangle versus Square problem.

A problem that goes away when you make the durn things immutable.
 
A

Andreas Leitgeb

ClassCastException said:
Simon Brooke said:
[Bird, Penguin extends Bird - should Bird be abstract?]
Actually, you won't ever find a real instance of Bird in nature that
isn't really of some more specific class. Be it Hawk, Craw, Ostrich,
Turkey, Chicken, ...
Misspellings like that really stick in my crow... :)
:-}

PS: the whole discussion of whether a class-hierarchy based on
natural species makes sense is besides the original point.
The rule of thumb would be: If you see a need for an exact
class-check to get your .equals() correct, then you're
better off making non-leaf classes abstract.
 
T

Tom Anderson

But I believe that is more:

Bird b = ObservationFactory.seeAt(point);

than:

Bird b = new Bird(attr);

:)

And of course, it goes without saying that:

Hand.getBird().equals(Collections.asList(Bush.getBird(), Bush.getBird()))

tom
 
L

Lew

Tom said:
And of course, it goes without saying that:

Hand.getBird().equals(Collections.asList(Bush.getBird(), Bush.getBird()))

That works as a pun, but as Java code would fail to yield 'true' under
conformant implementations of 'equals()'.

You'd need evaluation functions that return comparable values for a
bird in the hand vs. a collection of birds in the bush:


hand.eval( hand.getBird() ).equals( bush.eval( bush.getBirds().sublist( 0,
2 )))

or an extrinsic 'Evaluator' instance, 'evaluator' with method
'eval( Evaluable, Collection<Bird> )', where 'Hand' and 'Bush' both
implemant 'Evaluable':

evaluator.eval( hand,
Collections.asList( { hand.getBird() } )).equals( evaluator.eval( bush,
bush.getBirds().sublist( 0, 2 ) ))
 
T

Tom Anderson

[...]
Are you saying that class Bird ought not to be instantiable?

Yes.

There are no bird instances in the real world. They are all
instances of some type of bird.

That way lies madness. There are no Parrot instances in
the real world, only Polly and Snoofles and FeatheredBastard and
so on.

Why aren't those instances of Parrot?

tom
 
T

Tom Anderson

That works as a pun, but as Java code would fail to yield 'true' under
conformant implementations of 'equals()'.

I forgot to mention that Bird implements List<Bird>. Weird, but there you
go.

tom
 
T

Tom Anderson

Not really, but it does go away when you make the classes final.

You mean both of them? Then you either have to introduce a common base
class ParallelRightQuadrilateral, or be unable to write code that
manipulates boxes uniformly. Making Square a subtype of Rectangle is still
very attractive from a programmer-friendliness point of view. Immutability
is one way of overcoming the problems that introduces - and it really does
solve them. Squares are only non-Rectangular when they'r mutable, because
it's only their mutability that is not a superset of Rectangle's

tom
 
L

Lew

Tom said:
I forgot to mention that Bird implements List<Bird>. Weird, but there you
go.

That still would not be conformant, because the requirement for
'List#equals()' is, "Returns true if and only if the specified object
is also a list, both lists have the same size, and all corresponding
pairs of elements in the two lists are equal."

A List with one element cannot be equal to a List with two elements
under a conformant 'equals()'. Besides, it's not true that a bird in
the hand is *equal to* two in the bush, it's that a bird in the hand
is *worth* two in the bush.
 

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

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top