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?
Scala traits don't allow constructor parameters However, be aware that a class can extend only one abstract class.
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.
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.
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.
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
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With