Jakub Nowacki Jakub Nowacki - 22 days ago 6
Scala Question

Overriding abstract method of Java class in Scala with bounded inheritence

I have an abstract class in a library I wanted to implement in Scala, which has abstract copy method with bounded inheritance as follows:

// Java code
public abstract class Base {
public abstract <T extends Base> T copy();

When I create a class in Java it works fine, i.e.

public class FromBase extends Base {
public FromBase copy();

But if I try to do it in Scala the below gives
method 'copy' overrides nothing

class FromBase extends Base {
override def copy(): FromBase = new FromBase()

And the below IDE-suggested works but requires call with type
to work:

class FromBase extends Base {
override def copy[T <: Tuple](): T = (new FromBase).asInstanceOf[T]

Since the method can be called from Java, I need a copy without generic to work, as in the Java example.


The declaration of Base.copy says it can return whatever subtype of Base it's asked for. It's entirely valid to write

Base base = new FromBase;
AnotherBaseSubclass base2 = base.copy();
// same as AnotherBaseSubclass base2 = base.<AnotherBaseSubclass>copy();

This obviously can't work if FromBase.copy actual return type is FromBase. So the "warning" you are suppressing should be an error and Scala doesn't allow it.

It's likely that you actually need T on Base, not copy. If you fix this:

// Java code
public abstract class Base<T extends Base> {
      public abstract T copy();

// Scala
class FromBase extends Base[FromBase] {
    override def copy() = new FromBase

it will compile and not require any casts or suppressed warnings.