Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala single method interface implementation

Tags:

Does Scala have any syntactic sugar to replace the following code:

val thread = new Thread(new Runnable {    def run() {      println("hello world")    }     }) 

with something more like:

val thread = new Thread(() => println("hello world")) 

in cases when the trait/interface needs only one method to be implemented? If not, is there any chance to have this feature in Scala in the future? It is especially useful when one deals with Java classes.

I found a similar question asked three years ago: Generically implementing a Java Single-Abstract-Method interface with a Scala closure? The answer says we should have the feature in Scala 2.10. I've looked for Single Abstract Method keyword but I have not found anything. What's happened with the feature?

like image 228
Mequrel Avatar asked Apr 02 '14 18:04

Mequrel


People also ask

What is single method interface?

An interface with only one abstract method is called a functional interface, or a Single Abstract Method (SAM) interface. The functional interface can have several non-abstract members but only one abstract member. To declare a functional interface in Kotlin, use the fun modifier.

Does Scala have Interface?

Here is one major difference that Scala has from Java: there are no interfaces. There is no interface keyword. Yes, even though Scala is primarily a JVM language and often touted as a "better Java", it doesn't have interfaces.

Is Scala trait an interface?

Like a class, Traits can have methods(both abstract and non-abstract), and fields as its members. Traits are just like interfaces in Java.

What is an interface with a single method alternatively known as?

The interfaces with only one method are called Single Abstract Method(SAM) Interfaces. With the advent of Java8, such interfaces are also called Functional Interfaces.


2 Answers

Scala has experimental support for SAMs starting with 2.11, under the flag -Xexperimental:

Welcome to Scala version 2.11.0-RC3 (OpenJDK 64-Bit Server VM, Java 1.7.0_51). Type in expressions to have them evaluated. Type :help for more information.  scala> :set -Xexperimental  scala> val r: Runnable = () => println("hello world") r: Runnable = $anonfun$1@7861ff33  scala> new Thread(r).run hello world 

Edit: Since 2.11.5, this can also be done inline:

scala> new Thread(() => println("hello world")).run hello world 

The usual limitations about the expected type also apply:

  • it must define a single abstract method,
  • its primary constructor (if any) must be public, no-args, not overloaded,
  • the abstract method must take a single argument list,
  • the abstract method must be monomorphic.

According to the original commit by Adriaan, some of those restrictions may be lifted in the future, especially the last two.

like image 97
gourlaysama Avatar answered Oct 21 '22 23:10

gourlaysama


SAM types are supported using invokeDynamic since scala-2.12 similar to JDK-8, Below was tested on 2.12.3 - Release notes about SAM can be found here - http://www.scala-lang.org/news/2.12.0/

object ThreadApp extends App {   println("Main thread - begins")   val runnable: Runnable = () => println("hello world - from first thread")    val thread = new Thread(runnable)   println("Main thread - spins first thread")   thread.start()    val thread2 = new Thread(() => println("hello world - from second thread"))   println("Main thread - spins second thread")   thread2.start   thread.join()   thread2.join()    println("Main thread - end") } 
like image 37
Mohan Narayanaswamy Avatar answered Oct 21 '22 22:10

Mohan Narayanaswamy