Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala abstract type representing type of subclass

Tags:

scala

I'm looking for a way to define a method that returns a type T where T = the type of the subclass.

I know I could possibly do this using abstract types, but dislike the overhead of having to redefine T for each subclass.

Some sample code:

object Helper {
  def help[A <: MyClass](cls: A): Option[A] = { cls.foo() map { _.asInstanceOf[A] } }
}

class MyClass {
  type T <: MyClass
  def foo(): Option[T] = Some(this.asInstanceOf[T])
}

class ChildClass extends MyClass {
   type T = ChildClass
}

Possibly a new language feature has made this easier? Or can I use this.type in some way? It's important to me that I be able to define a helper class that can call into foo in this way.

like image 738
Pandora Lee Avatar asked Jul 29 '11 09:07

Pandora Lee


People also ask

What is abstract type in Scala?

Abstraction is the process to hide the internal details and showing only the functionality. In Scala, abstraction is achieved by using an abstract class. The working of the Scala abstract class is similar to Java abstract class. In Scala, an abstract class is constructed using the abstract keyword.

What is subclass in Scala?

Subclass. A class that inherits behaviors from another class, called superclass. In Scala, a class can only up have up to one superclass. Superclass. A class whose methods are inherited by one or more classes, called subclasses.

What is the abstract of member?

Abstract Members. A member of a class or trait is abstract if the member does not have a complete definition in the class. Abstract members are intended to be implemented in subclasses of the class in which they are declared. This idea is found in many object-oriented languages.

What does <: mean in Scala?

It means an abstract type member is defined (inside some context, e.g. a trait or class), so that concrete implementations of that context must define that type. However, there is a constraint that this type ( Currency ) must actually be a subtype of AbstractCurrency .


2 Answers

If you are always returning this, then you can indeed have as return type this.type. Or have you tried it already?

this.type is especially useful e.g. when you want to chain calls to the same object, or provide a static guarantee that you will be returning the same object (and not a copy). For instance, Buffers in Scala have the append operation :+, which returns a Buffer[A], and +=, which returns this.type. The former duplicates the mutable sequence; the latter guarantees that you update the original object.

like image 173
Jean-Philippe Pellet Avatar answered Nov 03 '22 09:11

Jean-Philippe Pellet


To follow up on Jean-Phillippe's answer, who wrote his exactly when I'm writing mine, here's the code:

trait SomeTrait {
  def foo: this.type = this
}

class UsesTrait extends SomeTrait

object Main {
  def main(args: Array[String]) {
    println((new UsesTrait).foo) // prints UsesTrait@<hash value>
  }
}
like image 43
Derek Wyatt Avatar answered Nov 03 '22 11:11

Derek Wyatt