From: Eric Sosman on
On 6/25/2010 6:55 PM, Arne Vajhøj wrote:
> On 25-06-2010 04:07, Simon Brooke wrote:
>> [...]
>> 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. Even Polly has no instances: There's Polly son of Polly
daughter of Polly son of Gawain, and PollyOfUnknownAntecedents,
and so on and so forth. Since the human mind is too small to
encompass all individual things in Nature or in imagination, it
is eventually necessary to generalize, to lump a whole aviary
of Pollys and Snoofleses and FeatheredBastards and so on into
Parrot. Or, let it be said, into Bird.

"Must every little attribute have a class all its own?"

--
Eric Sosman
esosman(a)ieee-dot-org.invalid
From: Arved Sandstrom on
Eric Sosman wrote:
> On 6/25/2010 6:55 PM, Arne Vajhøj wrote:
>> On 25-06-2010 04:07, Simon Brooke wrote:
>>> [...]
>>> 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. Even Polly has no instances: There's Polly son of Polly
> daughter of Polly son of Gawain, and PollyOfUnknownAntecedents,
> and so on and so forth. Since the human mind is too small to
> encompass all individual things in Nature or in imagination, it
> is eventually necessary to generalize, to lump a whole aviary
> of Pollys and Snoofleses and FeatheredBastards and so on into
> Parrot. Or, let it be said, into Bird.
>
> "Must every little attribute have a class all its own?"

I'm an amateur bird-watcher - very amateur - and I routinely classify
birds as Birds. I'm not totally helpless - if I spot crows or robins or
grackles or eagles I know what they are specifically - but most birds
for me are Birds. Usually only if they are ducks or geese can I tell you
exactly what they are. :-) For most of my mental models - and for quite
a few software models that I can imagine - Bird would suffice as a
template. A thing could genuinely and practically be an instance of Bird.

Problems like this is why I am less and less enthused with inheritance
and rigid class trees by the year. I've never actually used inheritance
a lot, and I use it less now than I ever did at the beginning of
learning OOP. My canonical example of inheritance frustration is
Vehicle: I've never come up with an inheritance tree starting with
Vehicle that doesn't leave a bad taste in my mouth. For a lot of my
mental models, and for quite a few software models that I can think of,
Vehicle is sufficient as a template. Objects could in fact be instances
of Vehicle.

Here's another example: Fastener. Go ahead and do up an inheritance tree
for Fastener that leaves you feeling warm and fuzzy.

I have very flat inheritance trees these days; always have had for the
most part. Aggregation/composition and interfaces go a lot further for
me than inheritance ever will. I don't mean to suggest that I make
minimal use of inheritance - I still use it a fair bit - but in recent
years almost all my use of it has been for implementation concerns like
re-using common code in JPA domain objects, _not_ for high-level design
per se.

Moving outside Java, and not focusing on any one other given language,
for me the object ideal is that of a fairly generic instance with
identity, that assumes characteristics and responsibilities as required,
and sheds them when it no longer needs them. If there were any inherent
"type" or classification, it might well be as high-level as Bird or
Vehicle or Human. A Human, at various points, might have the
characteristics and/or behaviours of a Student or Teacher or Employee or
Employer or Voter or Driver or DeceasedPerson or Felon, but those are
precisely characteristics and behaviours that the instance of Human
claims through composition/aggregation, and through implementation of
interfaces. There is no need to describe any of this through
inheritance, not in a high-level model/design sense, and I myself think
it's counter-productive.

I was going to extol some other languages in comparison to Java, but
then it occurred to me that while other languages might have features
that make some of these things easier to do, all of these concepts can
be implemented with no great difficulty in Java.

AHS
--
Any code of your own that you haven't looked at for six or more months
might as well have been written by someone else.
-- Eagleson's Law
From: Arved Sandstrom on
Eric Sosman wrote:
> 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.

AHS

--
Any code of your own that you haven't looked at for six or more months
might as well have been written by someone else.
-- Eagleson's Law
From: Arne Vajhøj on
On 26-06-2010 09:40, Patricia Shanahan wrote:
> Screamin Lord Byron wrote:
>> On 06/26/2010 03:15 AM, Eric Sosman wrote:
> ...
>>> to lump a whole aviary
>>> of Pollys and Snoofleses and FeatheredBastards and so on into
>>> Parrot. Or, let it be said, into Bird.
>>
>> You will lump it according to your lowest needed level of abstraction.
>> If your lowest level of abstraction is bird, then you'll only have
>> instances of the Bird class, but not instances of the Animal class. If
>> your generalization needs to be more specific, then you'd have instances
>> of the Parrot class, but not of the Bird and the Animal classes.
>
> 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
From: Arne Vajhøj on
On 26-06-2010 10:59, Arved Sandstrom wrote:
> Eric Sosman wrote:
>> 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