Reputation: 3456
Can't figure out what's wrong with this code:
trait NumberLike
{
def plus[T](a: T, b: T): T
}
class IntegerNumberLike extends NumberLike
{
def plus[Int](a: Int, b: Int): Int = 2 // type mismatch; found : scala.Int(2) required: Int
}
But if I do it this way, it works:
trait NumberLike[T]
{
def plus(a: T, b: T): T
}
class IntegerNumberLike extends NumberLike[Int]
{
def plus(a: Int, b: Int): Int = 2
}
So I got two questions:
Upvotes: 3
Views: 135
Reputation: 40510
Type parameters in methods are much like other parameters, the name of actual parameter isn't significant: plus[Int](a: Int, b: Int): Int
is exactly the same as plus[T](a: T, b: T): T
Now, it is easy to understand why plus[T](a: T, b: T): T = 2
does not compile, isn't it? Because 2
is not of type T
.
As to your second question, it is hard to answer exactly, because it is rather broad. In a nutshell, parametrized classes and methods define a template of a class or a method respectively. Think of it as a family of classes/methods rather than a single object. For example, instead of plus[T] (a: T, b: T): T
, one could have written:
def plus(a: Int, b: Int): Int
def plus(a: Long, b: Long): Long
def plus(a: Double, b: Double): Double
etc.
Or, instead of class NumberLike[T]
, you could have:
class IntLike
class LongLike
class DoubleLike
etc.
Looking at it this way, you can ask yourself a question, what it is you are designing: is it a family of classes or a family of methods? Answering that question will tell you whether you should parametrize a class, a method, or, perhaps, both ... Consider:
class Iterable[+A] {
...
def def reduceLeft[B >: A](op: (B, A) ⇒ B): B
...
}
Upvotes: 2
Reputation: 6242
The definition:
def plus[Int](a: Int, b: Int): Int
is equivalent to
def plus[T](a: T, b: T): T
For example, you could see it more clearly through the following example:
type Int = String
def main(args: Array[String]) {
val x: Int = "foo"
println(x)
}
where you get no errors and "foo" printed. Since you are only renaming your parametric type as Int (instead of T). That's why the compiler complains that Int (in this case the value of 2) and Int (your parametric type name) are not the same. I don't know if you can implement the plus function for specific types out of the parametric definition. You use class type parameters if the parameters apply to all the class, and method parameters if the parameters apply only to that method. It's just a matter of visibility and responsibility of the methods.
Upvotes: 1