Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / January 2006

Tip: Looking for answers? Try searching our database.

generics - overriding generically

Thread view: 
VisionSet - 08 Jan 2006 22:25 GMT
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
--
Mike W
Tony Morris - 08 Jan 2006 23:11 GMT
> How do I achieve this?
> I want to call the subclasses do method with FooImpl but define it more
[quoted text clipped - 16 lines]
> --
> Mike W

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.

Signature

Tony Morris
http://tmorris.net/

Chris Smith - 08 Jan 2006 23:52 GMT
> abstract class MyAbstract {
>
>     abstract do(<? extends Foo> foo); // ???
> }

<? extends Foo>, if it were legal, would be the same as Foo.  Remember
that a reference of type Foo *can* point to any subclass thereof.

> class MyImpl extends MyAbstract {
>
[quoted text clipped - 3 lines]
>
> 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.

Signature

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

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

VisionSet - 09 Jan 2006 00:14 GMT
> 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!

--
Mike W
Thomas Hawtin - 09 Jan 2006 00:31 GMT
>>That call is legal on an object of class MyAbstract (assuming a logical
>>interpretation of your plain wildcard type), but MyImpl doesn't have
[quoted text clipped - 6 lines]
> 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
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

VisionSet - 09 Jan 2006 00:27 GMT
> >>That call is legal on an object of class MyAbstract (assuming a logical
> >>interpretation of your plain wildcard type), but MyImpl doesn't have
[quoted text clipped - 8 lines]
>
> 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?

--
Mike W
Thomas Hawtin - 09 Jan 2006 00:18 GMT
> How do I achieve this?
> I want to call the subclasses do method with FooImpl but define it more
[quoted text clipped - 12 lines]
>
> 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) {
        // ...
    }
}

Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

VisionSet - 09 Jan 2006 00:25 GMT
> abstract class MyAbstract<T extends Foo> {
>      abstract void doStuff(T foo);
[quoted text clipped - 5 lines]
>      }
> }

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)

--
Mike W
Thomas Hawtin - 09 Jan 2006 00:37 GMT
> 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
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

VisionSet - 09 Jan 2006 00:38 GMT
> Here's what I've used to check javac (and my own sanity):

ooops I wrote

class MyImpl<FooImpl> extends MyAbstract {

--
Mike W
VisionSet - 09 Jan 2006 00:50 GMT
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 ....
}

>       abstract void doStuff(T foo);
> }
[quoted text clipped - 8 lines]
> class FooImpl implements Foo {
> }

--
Mike W
Thomas Hawtin - 09 Jan 2006 14:34 GMT
> okay now since this is static factory stylee...
>
[quoted text clipped - 6 lines]
>     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
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

VisionSet - 09 Jan 2006 17:02 GMT
> > okay now since this is static factory stylee...

> 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);

--
Mike W
Thomas Hawtin - 09 Jan 2006 20:00 GMT
>  static Component getTurnComponent(Turn turn) {
>   @SuppressWarnings("unchecked") // get SDK 1.5.0_06 for this feature
[quoted text clipped - 13 lines]
>
>  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
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Oliver Wong - 09 Jan 2006 22:22 GMT
> 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


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.