5

I'm currently working on a port of a jEdit plugin to write all code in Scala. However Im forced at a certain point to implement my own Comparator.

My simplified code is as follows:

class compare extends MiscUtilities.Compare {
  def compare(obj1: AnyRef, obj2: AnyRef): Int = 1
}

The MiscUtilities.Compare has the following signature when looking from IntelliJ

public static interface Compare extends java.util.Comparator {        
    int compare(java.lang.Object o, java.lang.Object o1);
}

However when im trying to compile my class I get a error saying:

error: class compare needs to be abstract, since method compare in trait Comparator of type (x$1: T,x$2: T)Int is not defined class compare extends MiscUtilities.Compare {

I have also tried with Any and java.lang.Object as types, but no luck so far.

Help is very much appreciated:)

Regards Stefan

Stefan
  • 725
  • 2
  • 9
  • 16
  • As you can see, the problem is difference in types. Where does `T` in `(x$1: T,x$2: T)Int` come from? – Alexey Romanov Jul 25 '10 at 12:05
  • Also, is `MiscUtilities.Compare` a class (as your question title says) or an interface (as shown in the body of the question?) – Alexey Romanov Jul 25 '10 at 12:06
  • 1
    MiscUtilities.Compare is an Interface sorry for the confusion. I dont know where they are coming from, as I understand it is the way it reads the signature of the MiscUtilities.Compare Interface compare method. – Stefan Jul 25 '10 at 12:10

3 Answers3

6

It may be impossible. If this is wrong, I would like to know.

EDIT: But you can do this instead:

// CompareImpl.java
abstract class CompareImpl implements MiscUtilities.Compare {
  public int compare(Object o, Object o1) {
    return doCompare(o, o1);
  }

  public abstract int doCompare(Object o, Object o1);
}

// MyCompare.scala
object MyCompare extends CompareImpl {
  def doCompare(a: AnyRef, b: AnyRef) = 0
}

So you still have to write some Java, but only one trivial class for each interface like MiscUtilities.Compare.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • Seems like you are right, I have found another way around the problem. Thank you all for your time. – Stefan Jul 25 '10 at 21:30
2

Producing a standalone example is the first step to solving these sort of problems.

 ~/code/scratch/raw: cat Compare.java 
interface Compare extends java.util.Comparator {
}
 ~/code/scratch/raw: cat MyCompare.scala 
object MyCompare extends Compare  {
  def compare(a: AnyRef, b: AnyRef) = 0
}
 ~/code/scratch/raw: scalac MyCompare.scala Compare.java 
MyCompare.scala:1: error: object creation impossible, since method compare in trait Comparator of type (x$1: T,x$2: T)Int is not defined
object MyCompare extends Compare  {
       ^

The temptation is to extend Comparator[AnyRef] directly from MyCompare, along with Compare:

object MyCompare extends java.util.Comparator[AnyRef] with Compare  {
  def compare(a: AnyRef, b: AnyRef) = 0
}

But this leads to:

error: illegal inheritance;
 self-type MyCompare.type does not conform to java.util.Comparator[AnyRef]'s selftype java.util.Comparator[AnyRef]

So I'm inclined to agree that this isn't possible, at least directly. Write the class in Java, delegating to Scala if need be.

retronym
  • 54,768
  • 12
  • 155
  • 168
1

Does it work if you put [AnyRef] after MiscUtilities.Compare? I.e.,

class Compare extends MiscUtilities.Compare[AnyRef] {   
  def compare(a1:AnyRef, a2:AnyRef) = 0       
}

I tried that with java.util.Comparator directly and the compiler seemed happy.

Dean Wampler
  • 2,141
  • 13
  • 10