Home > OS >  couldn't extend scala class from java class which has abstract function which takes inner class
couldn't extend scala class from java class which has abstract function which takes inner class

Time:09-28

I've scala - java polyglot project with scala version 2.13

Below is the standard project structure

    $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

Below is the Collector.java

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

    void close();
}

Below is the Function.java

public interface Function extends java.io.Serializable {}

Below is the Window.java

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

Below is the 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);
    }
}

Below is the ScalaProcessAllWindowFunctionWrapper.scala which extends JProcessAllWindowFunction

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 = ???
}

When I compile the project I get below error -

  > 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.

The project is on github here.

How can I fix this error?

CodePudding user response:

In ScalaProcessAllWindowFunctionWrapper modify the signature of method from

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

to

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

i.e. replace type projection JProcessAllWindowFunction[IN, OUT, W]#Context with path-dependent type Context aka this.Context. Type projection is a typical Java type and would work for overriding there but too rough type here in Scala.

In Java Context means JProcessAllWindowFunction<IN, OUT, W>.Context i.e. JProcessAllWindowFunction[IN, OUT, W]#Context in Scala. But in Scala Context means this.Context.

this.Context is a subtype of 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?

Also add modifier override to process in ScalaProcessAllWindowFunctionWrapper and remove modifier final from process in JProcessAllWindowFunction.

CodePudding user response:

You should be able to override it by using 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 = ???
}

You should also remove the final modifier on the process method

  • Related