Is it possible to achieve this?

M

Mark Space

Taras_96 said:
Agreed, pseudo-java code is good enough to describe a pattern.

Mark, your message higlighting that the resulting code was essentially
a switch statement clearly showed the problem... you should use OO in
polymorphism


I have to say that I'm still not 100% clear on what your original
question was. Did we manage to answer it?

I think this here indicates a "yes," but I was hoping for a message from
you indicating that we had got it.
 
T

Tom Anderson

I just re-read this last bit. What Tom are basically doing here is

Animal<?> animal;
Object o = animal.get();
if( o instanceof Cat ) {
Cat c = (Cat) o; // neighbor's cat
}
else {
Dog d = (Dog) o; // stray dog
}

which is VERY very messy indeed.

What? That bears no resemblance at all to the code i posted above! Indeed,
it's the exact opposite!

My *whole point* is that you might want to deal with Animals
polymorphically, ie not by instanceofing. But because Animal is a
parameterised type, you have to write it as such, even though the type
parameter carries no useful information in that situation.

If the interface of Animal looks like this:

public abstract class Animal<T extends Animal> {
public void processUnknownAnimal();
public float getMass();
public String getName();
}

That is, *with no use of the type parameter T*, then it seems weird to be
writing:

Animal<?> a;

Rather than:

Animal a;

Because the ? doesn't appear in the definitions of any of the methods you
might call!
Then the code above becomes:

Animal<?> animal;
Object o = animal.get();
if( o instanceof Animal ) {
Animal a = (Animal) o;
a.processUnkownAnimal();
}

Or better yet:

Animal<? extends Animal> animal;
Animal a = animal.get();
a.processUnkownAnimal();

I think i understand why we're going at cross purposes here: you're
thinking about Animals you might get from an initial Animal, out of that
parameterised list - i assume that's what get() is doing. So let's add
that, with a slightly more illuminating name, to the class:

public abstract class Animal<T extends Animal> {
private List<T> offspring;
public T getFirstOffspring() {
return offspring.get(0);
}
}

public class Cat extends Animal<Cat> {
}

public class Dog extends Animal<Dog> {
}

Now, T does appear in the methods. But it's still redundant, as i will
explain ...

First of all, note that the return type of getFirstOffspring is not
Object, but T, where T extends Animal, so your instanceof and cast are
unnecessary, you can just write:

Animal<?> animal;
Animal<?> a = animal.getFirstOffspring();
a.processUnknownAnimal();

Okay, now on to the redundancy. If you're dealing with Animals purely
polymorphically, then the binding of T will always be ? (or Animal<?> or
something, the two are much the same in this context). The only situation
where it might not be is if you were specifically dealing with one kind of
Animal. There, you could write:

Animal<Dog> myDog;

But there, we know from the definitions above that myDog isn't just an
Animal, it's a Dog. So we might as well just write:

Dog myDog;

And thus the type binding is once again unnecessary.

In java, though, there's no way to get away from it, because java doesn't
have a way of writing 'whatever the concrete class of this object is' is
type declarations. Not that i'm advocating one be added - the lack of it
is a minor annoyance, and i can't see a good way of doing it that doesn't
introduce other terrifying horrors.

tom
 
M

Mark Space

Tom said:
What? That bears no resemblance at all to the code i posted above!
Indeed, it's the exact opposite!

>
> Animal<?> animal;
> if (neighbourHasACat) animal = getNeighboursCat();
> else animal = getStrayDog();


I don't see how you do that with out casting the type of "animal" ...
the <?> can only stand for Object, you'll have to cast at some point to
do anything with it.

You might try to expand this into actual code, I think you'll see where
the problem is... or I will, not really sure what is going on here.

That is, *with no use of the type parameter T*, then it seems weird to
be writing:

Animal<?> a;


It's weird because you shouldn't do it.

Because the ? doesn't appear in the definitions of any of the methods
you might call!


Now, T does appear in the methods. But it's still redundant, as i will
explain ...


Not redundant, it parameterizes the return type.

Cat c = new Dog().getFirstOffspring(); // FAILS
Dog c = new Cat().getFirstOffspring(); // FAILS

That's what it does, makes those assignments fail at compile time.


something, the two are much the same in this context). The only
situation where it might not be is if you were specifically dealing with
one kind of Animal. There, you could write:

Animal<Dog> myDog;


I think my example was done quickly and was off somewhat. Animal should
probably be abstract. With out a real live use case here, it's kind of
hard to second guess these things.

We have two types of Animals right now, Animal<Dog> and Dog, which are
basically the same. The design is redundant. Making Animal abstract
would eliminate one of those.

In java, though, there's no way to get away from it, because java
doesn't have a way of writing 'whatever the concrete class of this
object is' is type declarations.


I wonder what you mean by this. Could you give an example -- in any
language -- of "whatever the concrete class of this object is?"
Hopefully in C++ or some other language I'm half-way familiar with, but
I'll take what you can offer.
 

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,776
Messages
2,569,602
Members
45,185
Latest member
GluceaReviews

Latest Threads

Top