generics - overriding generically

V

VisionSet

How do I achieve this?
I want to call the subclasses do method with FooImpl but define it more
generically in the superclass

abstract class MyAbstract {

abstract do(<? extends Foo> foo); // ???
}

class MyImpl extends MyAbstract {

do(FooImpl foo) {}

}

FooImpl extends Foo

TIA
 
T

Tony Morris

VisionSet said:
How do I achieve this?
I want to call the subclasses do method with FooImpl but define it more
generically in the superclass

abstract class MyAbstract {

abstract do(<? extends Foo> foo); // ???
}

class MyImpl extends MyAbstract {

do(FooImpl foo) {}

}

FooImpl extends Foo

TIA

It's difficult to determine your intention.
A couple of points to note:
1. do is a reserved keyword.
2. Your abstract class might better be implemented as an interface.

It looks to me like you want to use some contrived form of parametric
polymorphism.
If I'm right, you should consider refactoring your code to provide more
appropriate abstractions.
What you are attempting to do appears to have little to do with generics.
It is akin to attempting to "override" [sic] the equals method by having
some parameter type that is not java.lang.Object.
Of course, with generics you will receive a compile-time error.
 
C

Chris Smith

VisionSet said:
abstract class MyAbstract {

abstract do(<? extends Foo> foo); // ???
}

if it were legal said:
class MyImpl extends MyAbstract {

do(FooImpl foo) {}

}

FooImpl extends Foo

You really don't want to do that anyway. When MyImpl extends
MyAbstract, you are declaring that it's possible to use a reference to a
MyImpl object in any place that is declared to use a reference to a
MyAbstract. Your desired implementation would break that, since MyImpl
doesn't know what to do you say:

class FooImpl2 extends Foo { }
theAbstract.do(new FooImpl2());

That call is legal on an object of class MyAbstract (assuming a logical
interpretation of your plain wildcard type), but MyImpl doesn't have
defined behavior for it. That would violate type-safety.

In general, it's safe for subclasses to be more PERMISSIVE in
parameters, and more SPECIFIC in return types, but not the other way
around.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
V

VisionSet

That call is legal on an object of class MyAbstract (assuming a logical
interpretation of your plain wildcard type), but MyImpl doesn't have
defined behavior for it. That would violate type-safety.

What I'm trying to do is have polymorphic behaviour is a series of
subclasses. The abstract class instantiates and calls the methods on its
subclasses with arguments it also knows the concrete type of.
So I want to call the methods with that concrete type.
I know I can safely cast after the method is called, but I thought 1.5 might
have something up its sleeve to make it bit nicer.


Tony - I use do-while loops so rarely I actually forgot!
 
V

VisionSet

abstract class MyAbstract<T extends Foo> {
abstract void doStuff(T foo);
}

class MyImpl extends MyAbstract<FooImpl> {
void do(FooImpl foo) {
// ...
}
}

This is the sort of thing I was after, but to retro fit my compiler problem
to your example

MyImpl is not abstract, does not override abstract method do(Foo)
 
T

Thomas Hawtin

VisionSet said:
How do I achieve this?
I want to call the subclasses do method with FooImpl but define it more
generically in the superclass

abstract class MyAbstract {

abstract do(<? extends Foo> foo); // ???
}

class MyImpl extends MyAbstract {

do(FooImpl foo) {}

}

FooImpl extends Foo

To do something like that, the base type needs to be generic:

abstract class MyAbstract<T extends Foo> {
abstract void doStuff(T foo);
}

class MyImpl extends MyAbstract<FooImpl> {
void do(FooImpl foo) {
// ...
}
}
 
V

VisionSet

Thomas Hawtin said:
How does it know it's concrete type?

Concrete type of the method arguments
I assume you mean the base class
calls methods of (not on) its subclasses.
Yes

Base classes shouldn't know
their concrete type. Any code that does should be moved into the
concrete class.

Abstract Factories?
 
T

Thomas Hawtin

VisionSet said:
What I'm trying to do is have polymorphic behaviour is a series of
subclasses. The abstract class instantiates and calls the methods on its
subclasses with arguments it also knows the concrete type of.
So I want to call the methods with that concrete type.
I know I can safely cast after the method is called, but I thought 1.5 might
have something up its sleeve to make it bit nicer.

How does it know it's concrete type? I assume you mean the base class
calls methods of (not on) its subclasses. Base classes shouldn't know
their concrete type. Any code that does should be moved into the
concrete class.

Tom Hawtin
 
T

Thomas Hawtin

VisionSet said:
This is the sort of thing I was after, but to retro fit my compiler problem
to your example

MyImpl is not abstract, does not override abstract method do(Foo)

If I correct the second do method name, works fine for me...

The exact error message would be more helpful, together with relevant
source.

Here's what I've used to check javac (and my own sanity):

abstract class MyAbstract<T extends Foo> {
abstract void doStuff(T foo);
}

class MyImpl extends MyAbstract<FooImpl> {
void doStuff(FooImpl foo) {
// ...
}
}
interface Foo {
}
class FooImpl implements Foo {
}

Tom Hawtin
 
V

VisionSet

okay now since this is static factory stylee...

non-static class T cannot be referenced from a static context [at insert
line below]
abstract class MyAbstract<T extends Foo> {

static MyAbstract createMyAbstract(T foo) {
new ....
}
 
T

Thomas Hawtin

VisionSet said:
okay now since this is static factory stylee...

non-static class T cannot be referenced from a static context [at insert
line below]

abstract class MyAbstract<T extends Foo> {


static MyAbstract createMyAbstract(T foo) {
new ....
}

If you are calling a static method, then you need to know the class the
method belongs to. There is no polymorphism involved. So you should know
the argument types too.

Tom Hawtin
 
V

VisionSet

If you are calling a static method, then you need to know the class the
method belongs to. There is no polymorphism involved. So you should know
the argument types too.

Why should I?
All I know is I've got an abstract type to pass as an argument, it's up to
the static callee to deliver that type based on its more refined type.
Which it does but I need to supresss the warnings which build 1.5.0_06 does
apparantly.

static Component getTurnComponent(Turn turn) {
@SuppressWarnings("unchecked") // get SDK 1.5.0_06 for this feature
Class intf = getInterface(turn);
Class viewClass = rendererMap.get(intf);
Component comp = null;
try {
TurnView view = (TurnView)viewClass.newInstance();
comp = view.getComponent(turn); // warning: [unchecked] call to
getComponent(T)
}
catch(Exception ex) {
ex.printStackTrace();
}
return comp;
}

abstract Component getComponent(T turn);
 
T

Thomas Hawtin

VisionSet said:
static Component getTurnComponent(Turn turn) {
@SuppressWarnings("unchecked") // get SDK 1.5.0_06 for this feature
Class intf = getInterface(turn);
Class viewClass = rendererMap.get(intf);
Component comp = null;
try {
TurnView view = (TurnView)viewClass.newInstance();
comp = view.getComponent(turn); // warning: [unchecked] call to
getComponent(T)
}
catch(Exception ex) {
ex.printStackTrace();
}
return comp;
}

abstract Component getComponent(T turn);

I'm at a loss to see what you are trying to do.

If you are trying to do double-dispatch, then use the visitor pattern
(or cast both objects).

Certainly avoid Class.newInstance, if only because of its evil exception
handling.

Tom Hawtin
 
O

Oliver Wong

Thomas Hawtin said:
If you are calling a static method, then you need to know the class the
method belongs to. There is no polymorphism involved. So you should know
the argument types too.

What about something like this:

<pseudocode>

<BAR extends Foo> public static BAR
findBarThatSatisfySomeComplexCondition(List<BAR> myBars) {
return myBars.get(5);
}
</pseudocode>
?

- Oliver
 

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,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top