Scala:重写通用Java方法II

Scala:重写通用Java方法II,scala,scala-java-interop,Scala,Scala Java Interop,在Scala中,我需要覆盖以下给定的Java类和方法: public abstract class AbstractJava<T> { protected abstract T test(Class<? extends T> clazz); } public class ConcreteJava extends AbstractJava<Object> { @Override protected Object test(Class&l

在Scala中,我需要覆盖以下给定的Java类和方法:

public abstract class AbstractJava<T> {
    protected abstract T test(Class<? extends T> clazz);
}

public class ConcreteJava extends AbstractJava<Object> {
    @Override
    protected Object test(Class<?> clazz) {
        return null;
    }
}

// Scala
class ConcreteScala extends ConcreteJava {
    protected override def test(clazz: Class[_ <: AnyRef]): AnyRef =
        super.test(clazz)
}
当然,这些都是相同的类型(或变体)…!-所以Scala/Java继承有问题

多亏了米希德,才有了一个初步的解决方案:

class ConcreteScala3 {
  this: ConcreteJava =>
  protected override def test(clazz: Class[_ <: AnyRef]): AnyRef = {
    this.foo() // method of ConcreteJava
    null
  }
}
class-scala3{
这个:ConcreteJava=>

受保护的重写def test(clazz:Class[\up>使用原始类型重写Java方法时存在一些限制。请参阅相应的。特别是Martin Odersky的:“[…]在这些情况下,唯一可以做的事情是在Java中实现实现该方法的子类。[…]”

然而,我在前面的一篇文章中指出,对于某些情况,似乎有一个解决方案。诀窍是在Java端使用原始类型的存在类型显式声明重写Scala类的self类型

通过这种技术,我实现了以下工作:

public abstract class AbstractJava<T> {
    protected abstract T test(Class<T> clazz);
}

public class ConcreteJava extends AbstractJava<Object> {
    @Override
    protected Object test(Class<Object> clazz) {
        return null;
    }
}

class ConcreteScala extends ConcreteJava {
    this: AbstractJava[AnyRef] =>

    protected override def test(clazz: Class[AnyRef]): AnyRef = {
        super.test(clazz)
    }
}
公共抽象类AbstractJava{
保护抽象T检验(clazz类);
}
公共类ConcreteJava扩展了AbstractJava{
@凌驾
受保护对象测试(clazz类){
返回null;
}
}
类ConcreteScala扩展了ConcreteJava{
this:AbstractJava[AnyRef]=>
受保护的覆盖定义测试(clazz:Class[AnyRef]):AnyRef={
超级测试(clazz)
}
}
2017年再次提出了同样的问题

我认为这肯定是一个bug,我制造了一个问题

您可以应用以下变通方法

创建额外的Java类,通过重写
test()
将其“重命名”为
renameTest()
,并提供通过
concreteTest()
方法调用super
ConcreteJava.test()
的功能

public abstract class RenameJava extends ConcreteJava {
    public Object concreteTest(Class<?> c) {
        return super.test(c);
    }

    abstract protected Object renameTest(Class<?> c);

    @Override
    protected Object test(Class<?> c) {
        return renameTest(c);
    }
}
class ConcreteScala extends RenameJava {
  override protected def renameTest(c: Class[_]) = {
    // custom logic
    concreteTest(c)
  }
}

也许将这种类型的注释添加到Scala类中有助于:这个:java .UTI.IdultAc[s]=> Rational。谢谢,指向正确的方向。-请考虑发布(或对其进行详细说明)。作为一个答案,以获得一些应得的分数。非常感谢。另请参阅Scala中的编程-第二版,第31.3章存在类型。不幸的是,我不得不发现这种定义“自我类型”的方法不适用于我原始问题中的方法签名。-因此,必须还有另一种解决方案。。。
public abstract class RenameJava extends ConcreteJava {
    public Object concreteTest(Class<?> c) {
        return super.test(c);
    }

    abstract protected Object renameTest(Class<?> c);

    @Override
    protected Object test(Class<?> c) {
        return renameTest(c);
    }
}
class ConcreteScala extends RenameJava {
  override protected def renameTest(c: Class[_]) = {
    // custom logic
    concreteTest(c)
  }
}