Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > overloading with generic arguments

Reply
Thread Tools

overloading with generic arguments

 
 
Hendrik Maryns
Guest
Posts: n/a
 
      01-09-2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I have a complicated question about overloading with generic arguments.
I could not find a satisfying answer in Angelika Langer’s generics FAQ
(http://www.angelikalanger.com/Generi...ericsFAQ.html), or in
Sun’s generics tutorial
(http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf). I hope
someone here can read better than me.

I have a class which implements a DAG with labelled edges (actually an
MDD). Recently, I decided I needed non-determinism, so multiple edges
starting from one node can have the same label. This also requires the
possibility of there being more than one root (this will occur due to
certain manipulations of the DAG, such as removing a certain layer,
which can be the root layer).

This is implemented by Nodes which have children and so on. These are
inner classes and interfaces of a wrapping class, which stores the root
and offers manipulations of the DAG. This class used to have the
following simple layout:

public class CompactFunction {

private Node root;

public CompactFunction(Node root){
this.root = root;
}

public CompactFunction(BidiNode root){
this.root = root.getUnidirNode();
}

public CompactFunction removeVariable(int index) {...}

// more functions for manipulating and evaluating the function.

public interface Node {
// methods for all nodes
}

public class NonTerminalNode {
// nodes which have children, with methods to manipulate // the children
}

public class TerminalNode {
// nodes which have no children, but store a value
}
}

BidiNode is a node which also points up to its parents, and is used in
the construction of the DAG. Once it is constructed, I want to remove
the now no longer relevant information of the up-pointers, which is done
in the method getUnidirNode().

Now introducing nondeterminism seems simple: change root into a set of
nodes, alter the constructors and make all methods loop through the set
of nodes, as necessary. The problem is the second point; with the
following declaration:

CompactFunction(Set<BidiNode> roots) {
for (NonTerminalBidiNode root : roots) {
this.roots.add(root.getUnidirNode());
}
}

CompactFunction(Set<Node> roots) {
this.roots.addAll(roots);
}

Eclipse gives me the following errors:

Duplicate method CompactFunction(Set<CompactFunctionBuilder.BidiNod e>)
in type CompactFunction

for the first constructor, and

Duplicate method CompactFunction(Set<CompactFunction.Node>) in type
CompactFunction

for the second one. I suppose this is because erasure makes the method
signatures the same, but I thought overloading was handled by the
compiler, so this should work fine, right?

So the question: are these error messages correct, and if yes, what is
an alternative solution to achieve my goal?

Thanks for reading this far,
H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFFo3uqe+7xMGD3itQRAnkwAJ9Xh23/TQmfIAG4KHZ5wl+Xw8929QCdGE+g
8A4rE7vVIbTFukegB9VPdt8=
=AMcn
-----END PGP SIGNATURE-----
 
Reply With Quote
 
 
 
 
Hemal Pandya
Guest
Posts: n/a
 
      01-09-2007

Hendrik Maryns wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hi,
>
> I have a complicated question about overloading with generic arguments.


Not sure I understand all of this, but I get a similar error when I try
the following, which is perhaps a SSCCE of your code:

import java.util.Set;
class Node {}
class BidiNode extends Node {}

class X
{
X(Set<Node> r) {}
X(Set<BidiNode> r) {}
}

The error I get with Sun javac is: name clash: X(java.util.Set<Node>)
and X(java.util.Set<BidiNode>) have the same erasure

The following equivalent example does not have the compile error. Does
it solve your problem? Of course, it is a lot more verbose.

import java.util.Set;
class Node {}
class BidiNode extends Node {}

interface NodeSet extends Set<Node> {}
interface BidiNodeSet extends Set<BidiNode> {}

class X
{
X(NodeSet r) {}
X(BidiNodeSet r) {}

static class ABC extends java.util.HashSet<Node> implements NodeSet
{}
static void foo()
{
ABC abc = new ABC();
abc.add(new Node());
new X(abc);
}
}

 
Reply With Quote
 
 
 
 
Daniel Pitts
Guest
Posts: n/a
 
      01-10-2007

Hemal Pandya wrote:
> Hendrik Maryns wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> >
> > Hi,
> >
> > I have a complicated question about overloading with generic arguments.

>
> Not sure I understand all of this, but I get a similar error when I try
> the following, which is perhaps a SSCCE of your code:



The problem is that
public void something(Set<A> blah);
has the same signature as
public void something(Set<B> blah);
and also has the same signature as
public void something(Set blah);

because of erasure.

You have a couple of ways to solve your problem.
1. Use polymorphism of Node and move the differening behaviour from
your constructor to the Node itself. This is what I would recommend
based on what I've seen. That way you could have a Set<Node> which
contains BOTH Bidi nodes and otherwise.
You could also:
2. Have a different class that handles your other type of object.
3. Use Set<? extends Node> so that you have one constructor that takes
bother types of sets.
4. Have a different signature for the second type of constructor (add a
throw-away int)

 
Reply With Quote
 
Hendrik Maryns
Guest
Posts: n/a
 
      01-10-2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Daniel Pitts schreef:
> Hemal Pandya wrote:
>> Hendrik Maryns wrote:
>>> -----BEGIN PGP SIGNED MESSAGE-----
>>> Hash: SHA1
>>>
>>> Hi,
>>>
>>> I have a complicated question about overloading with generic arguments.

>> Not sure I understand all of this, but I get a similar error when I try
>> the following, which is perhaps a SSCCE of your code:

>
>
> The problem is that
> public void something(Set<A> blah);
> has the same signature as
> public void something(Set<B> blah);
> and also has the same signature as
> public void something(Set blah);
>
> because of erasure.


Yes, but I thought that which overloaded method to choose was decided at
compile time. Since the compiler knows about generics, it should not be
a problem.

> You have a couple of ways to solve your problem.
> 1. Use polymorphism of Node and move the differening behaviour from
> your constructor to the Node itself. This is what I would recommend
> based on what I've seen. That way you could have a Set<Node> which
> contains BOTH Bidi nodes and otherwise.


This would of course be the most elegant solution. The problem is: The
whole purpose of the Node class is to forget about the bidirectional
stuff. I.e. I have a FunctionBuilder, which needs up pointers, but once
the function has been built, I want to forget them, to save place.
Then, the functions are manipulated in ways that only use down pointers.
So I don’t want to clutter the Function class with anything related to
the bidirectional pointers. Ideally, I would even remove that
constructor, which I will probably do, eventually.

I could make BidiNode extend Node, but then I would have to introduce a
function in Node that is used in the constructor, which is overridden in
BidiNode. I do not want that function.

I think I’ll work with the design some more, and see if something nicer
comes out of it. I suspect that eventually, I will not need the
bidirectional nodes anymore, so then the problem solves itself.

I mainly posed the question out of curiosity why this error occurs.
Which still is not entirely clear, see above.

> You could also:
> 2. Have a different class that handles your other type of object.


I do not understand.

> 3. Use Set<? extends Node> so that you have one constructor that takes
> bother types of sets.


That would once again require BidiNode to extend Node.

> 4. Have a different signature for the second type of constructor (add a
> throw-away int)


Indeed, but *yuk*.

H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFFpMVre+7xMGD3itQRAkTbAJ9ss+IhsfakjfISYJt6eJ GQvjsIMwCdEil7
qCjN6OePkiks0A4DdVORIyw=
=tTqd
-----END PGP SIGNATURE-----
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
RE: Overloading __init__ & Function overloading Iyer, Prasad C Python 4 09-30-2005 08:01 PM
Re: Overloading __init__ & Function overloading Fredrik Lundh Python 0 09-30-2005 03:59 PM
Overloading __init__ & Function overloading Iyer, Prasad C Python 3 09-30-2005 02:17 PM
Re: Overloading __init__ & Function overloading Steve Holden Python 0 09-30-2005 01:58 PM
Re: Overloading __init__ & Function overloading Fredrik Lundh Python 0 09-30-2005 01:53 PM



Advertisments