From: Daniel Pitts on
On 6/23/2010 12:43 PM, Lew wrote:
> laredotornado wrote:
>>>> My question is, how can I tell if an object is a direct instantiation
>>>> of a class A and not a sub-class of the class A?
>>
>
> Mike Schilling wrote:
>>> Having to know this is probably an indication of poor design. But if you
>>> really need to, try
>>>
>>> if (a.getClass() == A.class)
>>
>
> Daniel Pitts wrote:
>> There is one use-case I can think of, and that is properly handling the
>> "equals" contract.
>>
>
> In that context the idiom is often
>
> if ( other.getClass() != getClass() )
> {
> return false;
> }
> ...
Thanks for expounding on my idea. Yes, that is the idiom used to handle
the use-case I was describing.

Actually, I would use:
if (other == this) { return true; }
if (other == null || other.getClass() != getClass() { return false; }


--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Eric Sosman on
On 6/23/2010 5:27 PM, Daniel Pitts wrote:
> [... using getClass() in equals() ...]
>
> Actually, I would use:
> if (other == this) { return true; }
> if (other == null || other.getClass() != getClass() { return false; }

Hmm. I usually write

if (other == null || other.getClass() != Thing.class)

Is there a reason to prefer one or the other?

--
Eric Sosman
esosman(a)ieee-dot-org.invalid
From: Daniel Pitts on
On 6/23/2010 2:47 PM, Eric Sosman wrote:
> On 6/23/2010 5:27 PM, Daniel Pitts wrote:
>> [... using getClass() in equals() ...]
>>
>> Actually, I would use:
>> if (other == this) { return true; }
>> if (other == null || other.getClass() != getClass() { return false; }
>
> Hmm. I usually write
>
> if (other == null || other.getClass() != Thing.class)
>
> Is there a reason to prefer one or the other?
>
To still allow subclasses to use the parent's equals() implementation
where they don't otherwise change the equal semantics.

E.G. if class SubThing only changed behavior of some method, then your
equals would return false against any SubThing.equals(SubThing), where
the first one could succeed.

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Eric Sosman on
On 6/23/2010 7:13 PM, Daniel Pitts wrote:
> On 6/23/2010 2:47 PM, Eric Sosman wrote:
>> On 6/23/2010 5:27 PM, Daniel Pitts wrote:
>>> [... using getClass() in equals() ...]
>>>
>>> Actually, I would use:
>>> if (other == this) { return true; }
>>> if (other == null || other.getClass() != getClass() { return false; }
>>
>> Hmm. I usually write
>>
>> if (other == null || other.getClass() != Thing.class)
>>
>> Is there a reason to prefer one or the other?
>>
> To still allow subclasses to use the parent's equals() implementation
> where they don't otherwise change the equal semantics.
>
> E.G. if class SubThing only changed behavior of some method, then your
> equals would return false against any SubThing.equals(SubThing), where
> the first one could succeed.

Fair enough. Thanks!

--
Eric Sosman
esosman(a)ieee-dot-org.invalid
From: Arne Vajhøj on
On 25-06-2010 04:07, Simon Brooke wrote:
> On Thu, 24 Jun 2010 12:45:02 +0000, Andreas Leitgeb wrote:
>
>> Eric Sosman<esosman(a)ieee-dot-org.invalid> wrote:
>>> On 6/23/2010 5:27 PM, Daniel Pitts wrote:
>>>> [... using getClass() in equals() ...] Actually, I would use:
>>>> if (other == this) { return true; }
>>>> if (other == null || other.getClass() != getClass() { return false; }
>>> Hmm. I usually write
>>> if (other == null || other.getClass() != Thing.class)
>>> Is there a reason to prefer one or the other?
>>
>> I'm rather surprised to see .equals() being called an exceptional
>> usecase for exact class-check.
>>
>> From previous discussions here and elsewhere, I had gathered, that
>> the "really correct" way to handle (non-trivial!) .equals() in a class
>> hierarchy would be to make all non-leaf-classes abstract.
>
> Making all non-leaf classes abstract is an example of poor design.

No.

It is good design.

> public class Bird {
> public boolean getCanFly() {
> return true;
> }
> }
>
> public class Penguin extends Bird {
> public boolean getCanFly() {
> return false;
> }
> }
>
> 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.


> Are you
> saying I ought to add a class:
>
> public class InstantiableBird extends Bird {} ?
>
> which has no new semantic content, which overrides or specialises
> nothing, and that's 'really correct'?

Usually you will only have subclasses for the specific birds
you need.

In the rare case that you need something to represent any bird
not represented by a specific sub class, then it would be good
design to have an OtherBird class.

Usually there will also be at least on abstract method
that requires overriding to return the display name
of the bird type.

Arne