加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala:覆盖通用Java方法II

发布时间:2020-12-16 09:19:32 所属栏目:安全 来源:网络整理
导读:在Scala中,我需要覆盖以下给定的Java类和方法: public abstract class AbstractJavaT { protected abstract T test(Class? extends T clazz);}public class ConcreteJava extends AbstractJavaObject { @Override protected Object test(Class? clazz) { re
在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)
}

我收到编译错误:

error: ambiguous reference to overloaded definition,both method test in class ConcreteJava of type 
(clazz: java.lang.Class[_])java.lang.Object

and method test in class AbstractJava of type 
(clazz: java.lang.Class[_ <: java.lang.Object])java.lang.Object

match argument types (Class[_$1]) and expected result type AnyRef

super.test(clazz)

我不会期望Scala编译器在超级调用中引用抽象方法.此外,我期望它首先引用直接超级类.

如何使Scala类编译?

谢谢!

编辑:

当离开super.test(clazz)调用时,会出现错误信息:

error: name clash between defined and inherited member:

method test:(clazz: Class[_ <: AnyRef])AnyRef and
method test:(clazz: java.lang.Class[_])java.lang.Object in class ConcreteJava

have same type after erasure: (clazz: java.lang.Class)java.lang.Object

protected override def test(clazz: Class[_ <: AnyRef]): AnyRef = null

那么当然这些是相同的类型(或变体)…! – 所以有Scala / Java继承有问题…

感谢michid,有一个初步的解决方案:

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

虽然我们不能从这里拨打超级电话.

回应仍然是最受欢迎的.

解决方法

使用原始类型覆盖Java方法时有一些限制.参见相应的 Scala ticket.具体来说,Martin Odersky的 comment:“[…]在这些情况下,唯一可以做的是在Java中实现一个实现该方法的子类.

不过,我在blog post早些时候指出,在某些情况下似乎有一个解决办法.诀窍是使用Java侧的原始类型的存在类型来显式声明重写Scala类的自身类型.

使用这种技术我得到以下工作:

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)
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读