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 / August 2007

Tip: Looking for answers? Try searching our database.

Clashing Interface methods

Thread view: 
rossum - 26 Aug 2007 19:46 GMT
Is there a way to deal with interfaces which have clashing method
definitions?

I am trying to write my own queue, based on a Hashtable:

 public class HashQueue<E>
     extends Hashtable<Integer, E>
     implements Queue<E> { ... }

This combination beings in interfaces Collection, Map, Dictionary and
Queue.  I am having problems with the method remove().  There are
different versions with different return values in the various
interfaces:

 Queue has:        E remove()
 Collection has:   boolean remove(Object o)
 Dictionary has:   E remove(E elem)

The Queue version has a different signature to the other two so that
is not a problem.  My problem is that the compiler is telling me that
the Dictionary remove does not match the Collection remove return
value and vice versa.  It seems that the compiler is treating Object
and E as the same.  How can I tell the compiler which of my
implementations of remove belongs to Collection and which to
Dictionary?  I have tried Collection.remove and (Collection)remove but
neither work.

A short example:

   interface FileStuff {
       String read();
   }
   
   interface ConsoleStuff {
       int read();
   }
   
   class Stuff implements FileStuff, ConsoleStuff {
       public String read() { return "Hello World!"; }
//        public String FileStuff.read() { return "Hello World!"; }
//        public String (FileStuff)read() { return "Hello World!"; }
       public int read() { return 42; }
   }

Is there a way round this problem?

Thanks in advance.

rossum
Patricia Shanahan - 26 Aug 2007 20:09 GMT
> Is there a way to deal with interfaces which have clashing method
> definitions?
[quoted text clipped - 4 lines]
>       extends Hashtable<Integer, E>
>       implements Queue<E> { ... }

I would avoid the direct extends/implements combination. Direct access
by your callers to the Hashtable would make it impossible for you to
ensure conformance to the Queue contract.

Instead, have a field:

Map<Integer, E> data = new Hashtable<Integer, E>();

and write the Queue methods using the "data" field to store the data.
You could extend AbstractQueue and only implement the methods it
requires, or implement Queue directly.

With this approach, there is no confusion between this.remove and
data.remove.

In the unlikely event that your callers really do need to access the
Map, you could provide a method getMap, but implement it something like
this:

public Map<Integer, E> getMap(){
  return Collections.unmodifiableMap(data);
}

which does not let the caller change your data Map.

Patricia
rossum - 26 Aug 2007 20:28 GMT
>> Is there a way to deal with interfaces which have clashing method
>> definitions?
[quoted text clipped - 4 lines]
>>       extends Hashtable<Integer, E>
>>       implements Queue<E> { ... }

Thanks for your reply.

>I would avoid the direct extends/implements combination. Direct access
>by your callers to the Hashtable would make it impossible for you to
>ensure conformance to the Queue contract.
I have done a similar thing in the past and there I overrode the base
class methods I didn't want and made them throw an Unsupported
Operation Exception

>Instead, have a field:
>
[quoted text clipped - 3 lines]
>You could extend AbstractQueue and only implement the methods it
>requires, or implement Queue directly.
This was my next option.  I take it from your reply that there is no
direct solution to my problem.  The obvious one was the C# use of
interface.method() to distinguish the declarations relevant to each
particular interface.  Since that didn't work I was not greatly
hopeful for a solution, as opposed to a workround.

>With this approach, there is no confusion between this.remove and
>data.remove.
[quoted text clipped - 10 lines]
>
>Patricia

Thanks for your help,

rossum
Joshua Cranmer - 26 Aug 2007 20:50 GMT
> I am trying to write my own queue, based on a Hashtable:
>
>   public class HashQueue<E>
>       extends Hashtable<Integer, E>
>       implements Queue<E> { ... }

Hashtable should be discarded in favor of HashMap whenever possible.

Also, is a HashQueue really a hash table? Probably not. Favor
composition over inheritance.

> This combination beings in interfaces Collection, Map, Dictionary and
> Queue.  I am having problems with the method remove().  There are
[quoted text clipped - 4 lines]
>   Collection has:   boolean remove(Object o)
>   Dictionary has:   E remove(E elem)

Generics are thorny issues. Technically speaking, there is nothing
forbidding the three implementations at bytecode level, but at the JLS
level, it appears that since the two remove methods have the same method
arguments after erasure, the last two methods cannot coexist.

> The Queue version has a different signature to the other two so that
> is not a problem.  My problem is that the compiler is telling me that
[quoted text clipped - 4 lines]
> Dictionary?  I have tried Collection.remove and (Collection)remove but
> neither work.

Whenever method hiding occurs, the resolution is:
((RandomClass)obj).method()

but that can only be done at method invocation.

> A short example:
>
[quoted text clipped - 14 lines]
>
> Is there a way round this problem?

No. Not in Java, not even in C++ (which has thornier issues relating to
multiple inheritance) AFAIK.

> Thanks in advance.
>
> rossum

Signature

Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

rossum - 26 Aug 2007 22:27 GMT
>> I am trying to write my own queue, based on a Hashtable:
>>
[quoted text clipped - 3 lines]
>
>Hashtable should be discarded in favor of HashMap whenever possible.
Good catch, thanks.

>Also, is a HashQueue really a hash table? Probably not. Favor
>composition over inheritance.
Another option would be a Priority Queue with the priority turned off.

>> This combination beings in interfaces Collection, Map, Dictionary and
>> Queue.  I am having problems with the method remove().  There are
[quoted text clipped - 9 lines]
>level, it appears that since the two remove methods have the same method
>arguments after erasure, the last two methods cannot coexist.
Given that Object was being seen the same as E I assumed that it was
erasure causing the problem.

>> The Queue version has a different signature to the other two so that
>> is not a problem.  My problem is that the compiler is telling me that
[quoted text clipped - 31 lines]
>No. Not in Java, not even in C++ (which has thornier issues relating to
>multiple inheritance) AFAIK.
I was afraid of that.

Thanks for your answer.

rossum

>> Thanks in advance.
>>
>> rossum
Daniel Pitts - 28 Aug 2007 00:10 GMT
> On Sun, 26 Aug 2007 19:50:30 GMT, Joshua Cranmer
>
[quoted text clipped - 76 lines]
>
> >> rossum

I believe LinkedList<E> implements Queue<E>, which might be exactly
what you want.
Roedy Green - 27 Aug 2007 09:16 GMT
>  Queue has:        E remove()
>  Collection has:   boolean remove(Object o)
>  Dictionary has:   E remove(E elem)

This is the problem Eiffel is so good at.

see http://mindprod.com/jgloss/eiffel.html

For Java you have to code around this somehow.  I would suggest
delegation.  Use one delegate class to implement one interface and
another class to implement the other, then glue them together with a
facade.

See http://mindprod.com/jgloss/facade.html
http://mindprod.com/jgloss/delegate.html

Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

rossum - 27 Aug 2007 12:39 GMT
>Is there a way to deal with interfaces which have clashing method
>definitions?
[quoted text clipped - 45 lines]
>
>rossum
There obviously being no direct way to solve the problem I ended up
using AbstractQueue with an internal HashMap:

 public class HashQueue<E>
     extends AbstractQueue<E> {

     private m_Data HashMap<Integer, E>;

 }

Thanks to everyone for your help.

rossum
Alexey - 27 Aug 2007 16:11 GMT
> >Is there a way to deal with interfaces which have clashing method
> >definitions?
[quoted text clipped - 59 lines]
>
> rossum

Is there a reason why you want to map integer values that I can only
assume represent queue positions to the elements of the queue?  If
your queue doesn't get elements removed from it midpoint, you should
be able to use a standard queue mechanism of push and pop.  This
mechanism is of course already implemented in Queue implementations
(add and remove methods).  If you need to dictate the order of the
queue upon addition of elements, PriorityQueue gives you that
functionality out of the box.  Just wondering about your design...

Also, when declaring variables and class fields, try to use as generic
a type as possible, interfaces being preferred.  From your example
above:
 private m_Data HashMap<Integer, E>;
won't compile until it's
 private HashMap<Integer, E> m_Data;
but should really be
 private Map<Integer, E> m_Data;

And if you do need to remove things from the middle of the queue, you
can still achieve that with a List object, which preserves any order
you give it.
rossum - 27 Aug 2007 22:13 GMT
>Is there a reason why you want to map integer values that I can only
>assume represent queue positions to the elements of the queue?
Correct.

>If your queue doesn't get elements removed from it midpoint, you should
>be able to use a standard queue mechanism of push and pop.
Push, pop, peek and drop.

>This mechanism is of course already implemented in Queue implementations
>(add and remove methods).
Queue is an Interface, and it was that which was part of my original
problem.  I dropped the interface when I moved to extending
AbstractQueue, which already implements Queue.  No need to include it
twice.

>If you need to dictate the order of the
>queue upon addition of elements, PriorityQueue gives you that
>functionality out of the box.  Just wondering about your design...
I want a plain FIFO Queue and it seems stupid to use a Priority Queue
with the priority effectively turned off.  All the heap overhead for
no purpose.  What I have is a HashMap with head and tail indexes.

>Also, when declaring variables and class fields, try to use as generic
>a type as possible, interfaces being preferred.  From your example
>above:
>  private m_Data HashMap<Integer, E>;
>won't compile until it's
My compiler said the same thing.  :)  Blame it on my first
professional language being Algol 60.

>  private HashMap<Integer, E> m_Data;
>but should really be
>  private Map<Integer, E> m_Data;
Good suggestion, which I have implemented.

>And if you do need to remove things from the middle of the queue, you
>can still achieve that with a List object, which preserves any order
>you give it.
I do not actually need to remove elements from the middle.  If I did
it wouldn't be a queue.

Thanks for your comments.

rossum
Lew - 28 Aug 2007 00:08 GMT
Alexey wrote:
>>  private HashMap<Integer, E> m_Data;
>> but should really be
>>  private Map<Integer, E> m_Data;

> Good suggestion, which I have implemented.

According to Sun's code conventions, which nearly everyone follows,
non-constant fields should be named without underscores.

Signature

Lew



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



©2009 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.