无法从 java class 扩展 scala class,它具有将内部 class 作为参数的抽象函数

couldn't extend scala class from java class which has abstract function which takes inner class as parameter

我有 scala - java 多语言项目,scala 版本 2.13

下面是标准的项目结构

    $scala-java-extend-demo on master
    ± tree .
    .
    ├── build.gradle.kts
    ├── gradlew
    ├── gradlew.bat
    ├── settings.gradle.kts
    └── src
        ├── main
             ├── java
             │   ├── Collector.java
             │   ├── Function.java
             │   ├── JProcessAllWindowFunction.java
             │   └── Window.java
             ├── resources
             └── scala
                 └── ScalaProcessAllWindowFunctionWrapper.scala


    24 directories, 15 files

下面是Collector.java

public interface Collector<T> {
    void collect(T record);

    void close();
}

下面是Function.java

public interface Function extends java.io.Serializable {}

下面是Window.java

public abstract class Window {
    public abstract long maxTimestamp();
}

下面是JProcessAllWindowFunction.java

public abstract class JProcessAllWindowFunction<IN, OUT, W extends Window> {

    private static final long serialVersionUID = 1L;

    public void process(Context context, Iterable<IN> elements, Collector<OUT> out){}

    public void clear(Context context) {}

    public abstract class Context {
        public abstract W window();
        public abstract <X> void output( X value);
    }
}

下面是扩展 JProcessAllWindowFunction

ScalaProcessAllWindowFunctionWrapper.scala
import java.lang

final class ScalaProcessAllWindowFunctionWrapper[IN, OUT, W <: Window] extends JProcessAllWindowFunction[IN, OUT, W] {
  override def process(context: JProcessAllWindowFunction[IN, OUT, W]#Context, elements: lang.Iterable[IN], out: Collector[OUT]): Unit = ???
}

当我编译项目时出现以下错误 -

  > scala-java-extend-demo on master $
  ± gradle clean build
  
  > Task :compileScala FAILED
  [Error] /Users/myuser/Coding/misc/scala-java-extend-demo/src/main/scala/ScalaProcessAllWindowFunctionWrapper.scala:4: method process overrides nothing.
  Note: the super classes of class ScalaProcessAllWindowFunctionWrapper contain the following, non final members named process:
  def process: ((context: _1.Context, elements: Iterable[IN], out: Collector[OUT]): Unit) forSome { val _1: ScalaProcessAllWindowFunctionWrapper[IN,OUT,W] }
  one error found
  
  FAILURE: Build failed with an exception.

项目在 github here.

我该如何解决这个错误?

ScalaProcessAllWindowFunctionWrapper中修改方法的签名

def process(context: JProcessAllWindowFunction[IN, OUT, W]#Context, elements: lang.Iterable[IN], out: Collector[OUT]): Unit = ???

def process(context: Context, elements: lang.Iterable[IN], out: Collector[OUT]): Unit = ???

即将类型投影 JProcessAllWindowFunction[IN, OUT, W]#Context 替换为路径相关类型 Context 又名 this.Context。类型投影是一种典型的 Java 类型,可以在那里覆盖,但在 Scala 中这里的类型太粗糙了。

在 Java 中 Context 表示 JProcessAllWindowFunction<IN, OUT, W>.Context 即 Scala 中的 JProcessAllWindowFunction[IN, OUT, W]#Context。但在 Scala 中 Context 表示 this.Context.

this.Contextx.Context(对于特定的 x: JProcessAllWindowFunction[IN, OUT, W])是 JProcessAllWindowFunction[IN, OUT, W]#Context.

的子类型

Why does one select Scala type members with a hash instead of a dot?

What are type projections useful for?

What does the `#` operator mean in Scala?

What is meant by Scala's path-dependent types?

What is the difference between path-dependent types and dependent types?

Are path-dependent types type projections?

同时将修饰符 override 添加到 ScalaProcessAllWindowFunctionWrapper 中的 process 并从 JProcessAllWindowFunction 中的 process 中删除修饰符 final

您应该可以使用 this:

覆盖它
import java.lang

final class ScalaProcessAllWindowFunctionWrapper[IN, OUT, W <: Window] extends JProcessAllWindowFunction[IN, OUT, W] {
  override def process(context: this.Context, elements: lang.Iterable[IN], out: Collector[OUT]): Unit = ???
}

您还应该删除 process 方法上的 final 修饰符