Implementing Java Interfaces and Generics

30 08 2009

In an earlier post I asked for an implementation of the following Java interface in Scala:

public interface Iterator2 extends java.util.Iterator {}  

The solution was to use a combination of self types and existential types. However, some comments made me aware of Ticket #1737 where a more general form of the problem is discussed. Given the following Java code:

public interface A<T> {
    void run(T t);
    T get();
}

public abstract class B implements A {}

How could B be implemented in Scala? My previous approach is not sufficient here since for implementing the run() method, one needs to be able to refer to the existential type in run()‘s parameter list:

class C extends B {
  this: A[_] =>
      
  def run(t:???) {} // What should go here for t's type?
  def get = "hello world"
}

So what we need is a way to name the existential type used in the self type (that is the type parameter to A) such that we can refer to it in the parameter list of the run() method. Here is my shot:

class D {
  type Q = X forSome { type X; }
}

class C extends B {
  this: A[D#Q] =>
      
  def run(t:D#Q ) {}
  def get: D#Q = "hello world"
}

Unfortunately this results in a compilation error with Scala 2.7.5

error: class C needs to be abstract, since method run in trait A of type (T)Unit is not defined

and in a AssertionError for Scala 2.8.0.r18604-b20090830020201

Exception in thread "main" java.lang.AssertionError: assertion failed: michid.iterator.A[T]
at scala.Predef$.assert(Predef.scala:107)
at scala.tools.nsc.symtab.Types$TypeRef.transform(Types.scala:1417)
at scala.tools.nsc.symtab.Types$TypeRef$$anonfun$baseTypeSeq$3.apply(Types.scala:1588)
...

I created Ticket #2091 for these problems.

About these ads

Actions

Information

2 responses

25 07 2010
Alexey Romanov

Well, you _can_ do this:

(in Java):
public abstract class B1 extends B {
abstract void doRun(Object t);

abstract Object doGet();

public void run(Object t) { return doRun(Object t); }

public Object get() { return doGet(); }
}

and you can now extend B1 in Scala without problems…

25 07 2010
Alexey Romanov

And now I looked at the linked post and saw this solution was given already. D’oh.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




Follow

Get every new post delivered to your Inbox.

%d bloggers like this: