Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala class constructors and abstract types

I want to use an abstract type rather than a type parameter.

In my generic classes constructor, I want to have a parameter of the generic type, but the code doesn't compile:

class SomeOtherClass(val s: S){
    type S
}

The scala compiler error is "not found: type S"

If I use a type parameter instead of an abstract type, then it works:

class SomeClass[T](val t: T){
    //...
}

Does scala force me to use a type parameter rather than an abstract type, if I want to have a generic parameter in the constructor?

Is there another way to do this?

like image 341
John Smith Avatar asked Aug 07 '12 11:08

John Smith


People also ask

Can abstract class have constructor in Scala?

Scala traits don't allow constructor parameters However, be aware that a class can extend only one abstract class.

What is abstract type in Scala?

In Scala, an abstract class is constructed using the abstract keyword. It contains both abstract and non-abstract methods and cannot support multiple inheritances. A class can extend only one abstract class.

What is constructor class in Scala?

Class constructors In Scala, the primary constructor of a class is a combination of: The constructor parameters. Methods that are called in the body of the class. Statements and expressions that are executed in the body of the class.

Does Scala have constructor?

Scala ConstructorThere are two types of constructor in Scala – Primary and Auxiliary. Not a special method, a constructor is different in Scala than in Java constructors. The class' body is the primary constructor and the parameter list follows the class name. The following, then, is the default primary constructor.


2 Answers

You're pretty much forced to use generic type parameters in that case. You can work around it by declaring the type outside the class but then you'd need to instantiate the wrapper and then the object and it would get ugly pretty quickly.

trait FooDef {
  type T
  class Foo(val x: T)
}
val ifd = new FooDef { type T = Int }
val ifoo = new ifd.Foo(5)
val sfd = new FooDef { type T = String }
val sfoo = new sfd.Foo("hi")
def intFoos(f: fd.Foo forSome { val fd: FooDef {type T = Int} }) = f.x + 1
like image 172
Kaito Avatar answered Oct 19 '22 18:10

Kaito


When the abstract type isn't specified, your class needs to be abstract. So you don't need the parameter at all. The equivalent with an abstract type would be:

abstract class SomeOtherClass {
  type S
  val s: S 
}

Then at use-site:

val x = new SomeOtherClass {
  type S = String
  val s = "abc"
}

Without the parameter, the abstract class here is equivalent to a trait. You're better off using a trait because it's less restrictive (you can only extend one base class).

like image 45
Luigi Plinge Avatar answered Oct 19 '22 18:10

Luigi Plinge