Signature collision between methods in superclass and interface:suggestions?


S

Simon Brooke

I've been writing Java since Java 1.0, but three years ago I was switched
to the dark side, so I've been writing C# for a while; I'm refreshing my
Java skills and am certainly rusty. If this is a silly question please do
say so.

I'm trying to build a tiered map, such that when the map is searched for
a key, each tier is searched successively starting from the top one until
a value is found; in this way upper-tier key/value pairs can mask key/
value pairs in lower layers.

So I've started out:

/**
* A tiered map is a bit like a wedding cake. Each layer contains
* key/value pairs which mask key/value pairs in lower layers.
* @author simon
*
* @param <K> The class of which keys in this tiered map are members
* @param <V> The class of which values in this tiered map are members
*/
public class TieredMap<K,V> extends LinkedList<Map<K,V>> implements
Map<K,V>

Things all go swimmingly until I get to the method Remove(Object key).
The Map interface wants

public V remove(Object key)

but the superclass wants

public boolean remove( Object key)

Is there any way in which both can be satisfied?

Yes, I appreciate that the alternative would be to make TieredMap extend
Object and store the list of tiers a private instance variable; but that
seems a bit clunky. Is there a generic (pun intended) solution to this
problem?
 
Ad

Advertisements

L

Lew

I've been writing Java since Java 1.0, but three years ago I was switched
to the dark side, so I've been writing C# for a while; I'm refreshing my
Java skills and am certainly rusty. If this is a silly question please do
say so.

I'm trying to build a tiered map, such that when the map is searched for
a key, each tier is searched successively starting from the top one until
a value is found; in this way upper-tier key/value pairs can mask key/
value pairs in lower layers.

So I've started out:

/**
* A tiered map is a bit like a wedding cake. Each layer contains
* key/value pairs which mask key/value pairs in lower layers.
* @author simon
*
* @param<K> The class of which keys in this tiered map are members
* @param<V> The class of which values in this tiered map are members
*/
public class TieredMap<K,V> extends LinkedList<Map<K,V>> implements
Map<K,V>

Things all go swimmingly until I get to the method Remove(Object key) [sic].
The Map interface wants

public V remove(Object key)

but the superclass wants

public boolean remove( Object key)

Is there any way in which both can be satisfied?

Yes, I appreciate that the alternative would be to make TieredMap extend
Object and store the list of tiers a private instance variable; but that
seems a bit clunky. Is there a generic (pun intended) solution to this
problem?

I don't think there's any way to inherit both List and Map; they're just too
different.

Instead of inheriting List, compose it. Your description indicates that you
want your type to /be-a/ Map, so don't have it /be-a/ List also.

The public shouldn't know that your type is a List, much less a LinkedList.
That should be a hidden detail of the implementation.
 
M

markspace

Simon said:
Is there any way in which both can be satisfied?


Not directly, no, I don't think so.

What you might consider is creating an object, then creating separate
List and Map views of that object.

public class TieredMap<K,V> // extends Object
{
....
public List<Map<K,V>> asList() { // gets a List interface
...

public Map<K,V> asMap() { // gets a Map interface
...

}

Theoretically best of both worlds here, although slightly inconvenient
to use.
 
R

Roedy Green

Is there any way in which both can be satisfied?

Eiffel has a renaming feature to resolve such conflicts, but within
Java I think you are stuck.

Do you really want your object to behave directly as both a LinkedList
and a TierMap? That sounds like a very weird duck. LinkedList is a
detail of implementation, not likely something you want your clients
to fiddle with directly.

So create a class that does not extend LinkedList, but rather has
private field pointing to one. You can wrap some methods to fiddle
with the LinkedList externally if necessary.

--
Roedy Green Canadian Mind Products
http://mindprod.com

There is no harm in being sometimes wrong especially if one is promptly found out.
~ John Maynard Keynes (born: 1883-06-05 died: 1946-04-21 at age: 62)
 
S

Simon Brooke

Eiffel has a renaming feature to resolve such conflicts, but within Java
I think you are stuck.

Do you really want your object to behave directly as both a LinkedList
and a TierMap? That sounds like a very weird duck. LinkedList is a
detail of implementation, not likely something you want your clients to
fiddle with directly.

No, it doesn't need to behave like a linked list at all, except that the
caller needs to be able to add and remove tiers. In fact, a stack might
be a better implementation than a linked list - the caller does not need
to have direct access to lower level tiers.
So create a class that does not extend LinkedList, but rather has
private field pointing to one. You can wrap some methods to fiddle with
the LinkedList externally if necessary.

Looks like that will have to be the solution. Thanks.

(oh, and thanks to everyone else who responded).

Simon
 
L

Lew

Simon said:
No, it doesn't need to behave like a linked list at all, except that the
caller needs to be able to add and remove tiers. In fact, a stack might
be a better implementation than a linked list - the caller does not need
to have direct access to lower level tiers.

This proves Roedy's point beautifully. If you do expose the 'List' (let alone
'LinkedList') detail of implementation, you commit to that as part of the
public contract and cannot easily change to 'Stack' when you realize that it
would improve things. Keep that part hidden as suggested.


Only expose publicly those aspects that are part of the public contract of the
type.
 
Ad

Advertisements

S

Simon Brooke

This proves Roedy's point beautifully. If you do expose the 'List' (let
alone 'LinkedList') detail of implementation, you commit to that as part
of the public contract and cannot easily change to 'Stack' when you
realize that it would improve things. Keep that part hidden as
suggested.

Good point. Thanks.
 

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

Top