How do you provide overloaded constructors in Scala?
It's worth explicitly mentioning that Auxiliary Constructors in Scala must either call the primary constructor (as in landon9720's) answer, or another auxiliary constructor from the same class, as their first action. They cannot simply call the superclass's constructor explicitly or implicitly as they can in Java. This ensures that the primary constructor is the sole point of entry to the class.
class Foo(x: Int, y: Int, z: String) {
// default y parameter to 0
def this(x: Int, z: String) = this(x, 0, z)
// default x & y parameters to 0
// calls previous auxiliary constructor which calls the primary constructor
def this(z: String) = this(0, z);
}
class Foo(x: Int, y: Int) {
def this(x: Int) = this(x, 0) // default y parameter to 0
}
As of Scala 2.8.0 you can also have default values for contructor- and method parameters. Like this
scala> class Foo(x:Int, y:Int = 0, z:Int=0) {
| override def toString() = { "Foo(" + x + ", " + y + ", " + z + ")" }
| }
defined class Foo
scala> new Foo(1, 2, 3)
res0: Foo = Foo(1, 2, 3)
scala> new Foo(4)
res1: Foo = Foo(4, 0, 0)
Parameters with default values must come after the ones with no default values in the parameter list.
While looking at my code, I suddenly realized that I did kind of an overload a constructor. I then remembered that question and came back to give another answer:
In Scala, you can’t overload constructors, but you can do this with functions.
Also, many choose to make the apply function of a companion object a factory for the respective class.
Making this class abstract and overloading the apply function to implement-instantiate this class, you have your overloaded “constructor”:
abstract class Expectation[T] extends BooleanStatement {
val expected: Seq[T]
…
}
object Expectation {
def apply[T](expd: T ): Expectation[T] = new Expectation[T] {val expected = List(expd)}
def apply[T](expd: Seq[T]): Expectation[T] = new Expectation[T] {val expected = expd }
def main(args: Array[String]): Unit = {
val expectTrueness = Expectation(true)
…
}
}
Note that I explicitly define each apply to return Expectation[T], else it would return a duck-typed Expectation[T]{val expected: List[T]}.
Try this
class A(x: Int, y: Int) {
def this(x: Int) = this(x, x)
def this() = this(1)
override def toString() = "x=" + x + " y=" + y
class B(a: Int, b: Int, c: String) {
def this(str: String) = this(x, y, str)
override def toString() =
"x=" + x + " y=" + y + " a=" + a + " b=" + b + " c=" + c
}
}
Related
Here's an example that confused me a lot.
class Point(val xc: Int, val yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("x 的坐标点 : " + x);
println ("y 的坐标点 : " + y);
}
}
class Location(override val xc: Int,
override val yc: Int,
val zc: Int) extends Point(xc, yc) {
var z: Int = zc
def move(dx: Int, dy: Int, dz: Int) {
x = x + dx
y = y + dy
z = z + dz
println ("x 的坐标点 : " + x);
println ("y 的坐标点 : " + y);
println ("z 的坐标点 : " + z);
}
}
Why does the method move not need an override modifier? It isn't an abstract method in class Point, it should be decorated with "override", I think. Actually, when I add an "override", error happens.
And for xc, yc, why "override" is a nessesary?
I'm really confused with that.
I have python experience and very little Java experience.
Any help will be appreciated, thanks!
for xc, yc, why "override" is a nessesary?
Nope, its not necessary. In your case you're making it val again in your child class, which is not necessary since you already defined them as val in parent class. (simply remove val from child class)
scala> class Point(val xc: Int, val yc: Int) {}
defined class Point
scala> class Location(xc: Int, yc: Int, val zc :Int) extends Point(xc, yc){}
defined class Location
Why the method "move" doesn't need an "override"?
Because your move method in Parent class is not an abstract method
or your signature is different in child class than parent class.
eg.
abstract class Point(val xc: Int, val yc: Int) {
abstract def doWhatever() : Unit
}
class Location(xc: Int, yc: Int, val zc: Int) extends Point(xc, yc) {
override def doWhatever(): Unit = ??? // override is optional
}
You could have aldo overridden if the signature was same, so that when you call childClass.move(), the overridden method is invoked.
class Point(val xc: Int, val yc: Int) {
def move() = println("parent::whatever")
}
class Location(xc: Int, yc: Int, val zc: Int) extends Point(xc, yc) {
override def move() = println("child::whatever") //override is required
}
example invoking move method,
for a parent,
scala> val point = new Point(1, 2)
point: Point = Point#66813e6e
scala> point.move()
parent::whatever
for a child,
scala> val location1 = new Location(1, 2, 3)
location1: Location = Location1#233db8e9
scala> location1.move()
child::whatever
I'm trying to mock a function like
def foo(x: A, y: B, z: C = blah)
where blah is a java connection object that I don't want to create on the spot
However when I try to stub it like
(object.foo _)
.stubs(a, b)
It errors out and says overloaded method value stubs with alternatives...
because it's looking for the third parameter. Is there anyway to get around this.
I agree with Matt, but want to point out there is a wildcard syntax in ScalaMock (*) - http://scalamock.org/user-guide/matching/
trait Foo {
def foo(x: Int, y: Int, z: Int = 0): Int
}
val a: Int = ???
val b: Int = ???
val m = mock[Foo]
m.foo _ stubs(a, b, *)
You can use a wildcard when you're stubbing out your method.
The following test passes and I think is what you're looking for:
class DefaultParameterTest extends FlatSpec with Matchers with MockFactory {
class A {
def foo(x: Int, y: Int, z: Int = 0): Int = 0
}
it should "work with a default parameter" in {
val bar = mock[A]
(bar.foo _).stubs(1, 2, _: Int).returning(5)
bar.foo _ expects(1, 2, 0) returning 5 once()
bar.foo(1, 2)
}
}
I have the following function which generates a Uniform distributed value between 2 bounds:
def Uniform(x: Bounded[Double], n: Int): Bounded[Double] = {
val y: Double = (x.upper - x.lower) * scala.util.Random.nextDouble() + x.lower
Bounded(y, x.bounds)
}
and Bounded is defined as follows:
trait Bounded[T] {
val underlying: T
val bounds: (T, T)
def lower: T = bounds._1
def upper: T = bounds._2
override def toString = underlying.toString + " <- [" + lower.toString + "," + upper.toString + "]"
}
object Bounded {
def apply[T : Numeric](x: T, _bounds: (T, T)): Bounded[T] = new Bounded[T] {
override val underlying: T = x
override val bounds: (T, T) = _bounds
}
}
However, I want Uniform to work on all Fractional[T] values so I wanted to add a context bound:
def Uniform[T : Fractional](x: Bounded[T], n: Int): Bounded[T] = {
import Numeric.Implicits._
val y: T = (x.upper - x.lower) * scala.util.Random.nextDouble().asInstanceOf[T] + x.lower
Bounded(y, x.bounds)
}
This works swell when doing a Uniform[Double](x: Bounded[Double]), but the other ones are impossible and get a ClassCastException at runtime because they can not be casted. Is there a way to solve this?
I'd suggest defining a new type class that characterizes types that you can get random instances of:
import scala.util.Random
trait GetRandom[A] {
def next(): A
}
object GetRandom {
def instance[A](a: => A): GetRandom[A] = new GetRandom[A] {
def next(): A = a
}
implicit val doubleRandom: GetRandom[Double] = instance(Random.nextDouble())
implicit val floatRandom: GetRandom[Float] = instance(Random.nextFloat())
// Define any other instances here
}
Now you can write Uniform like this:
def Uniform[T: Fractional: GetRandom](x: Bounded[T], n: Int): Bounded[T] = {
import Numeric.Implicits._
val y: T = (x.upper - x.lower) * implicitly[GetRandom[T]].next() + x.lower
Bounded(y, x.bounds)
}
And use it like this:
scala> Uniform[Double](Bounded(2, (0, 4)), 1)
res15: Bounded[Double] = 1.5325899033654382 <- [0.0,4.0]
scala> Uniform[Float](Bounded(2, (0, 4)), 1)
res16: Bounded[Float] = 0.06786823 <- [0.0,4.0]
There are libraries like rng that provide a similar type class for you, but they tend to be focused on purely functional ways to work with random numbers, so if you want something simpler you're probably best off writing your own.
Is it possible to initialize a class parameter with a function in Scala?
Example:
def square(x: Int) = x*x
class Foo(val x: Int = square(x))
This doesn't compile but I hope you get the idea.
Hard to guess what you're trying to achieve, but let me have a go:
class Foo private (val x: Int)
object Foo {
def apply(x: Int) = new Foo(square(x))
}
Note that if you try this in the REPL, you must enter both the class and its companion object at the same time (in paste mode, via :pa), or the object Foo won't have access to the private class constructor.
This applies the square function to the parameter x before creating a Foo instance:
scala> Foo(3).x
res1: Int = 9
This is not possible because you try to calculate x based on x (without having any kind of base case). You could do the following:
class Foo(_x: Int) {
val x = square(_x)
}
println(new Foo(10).x) // 100
EDIT
You could also generalise this and implicitly pass a function to the class constructor that transforms x:
implicit val square = (x: Int) => x*x
class Foo(private val _x: Int)(implicit f: Int => Int) {
val x = f(_x)
}
println(new Foo(10).x) // 100
This unfortunately doesn't compile as-is (Scala 2.9.2, 2.10.0), because there is another implicit in scope (Predef.conforms). I don't know how to overcome this ambiguity, but it should certainly be possible.
Here it is.. you can initialize a class with a function ! :)
class Foo(f : Int => Int)
def square(x : Int) = x*x
val foo = new Foo(square)
Or Probably you must be looking for this.
class Foo(f : Int => Int, _p1 : Int){
val p1 = f(_p1)
}
def square(x : Int) = x*x //> square: (x: Int)Int
def add2(x : Int) = x+2 //> add2: (x: Int)Int
val fooSqr = new Foo(square,5)
fooSqr.p1 //> res0: Int = 25
val fooAdd2 = new Foo(add2,5)
fooAdd2.p1 //> res1: Int = 7
In general you can use arbitrary expressions when defining the default value (source).
Your problem is that you can not use x on the right hand side of the initialization, because x is probably neither declared nor initialized at that point.
I have a function with two parameter lists that I am trying to partially apply and use with currying. The second parameter list contains arguments that all have default values (but not implicit). Something like this:
def test(a: Int)(b: Int = 2, c: Int = 3) { println(a + ", " + b + ", " + c); }
Now, the following is all fine:
test(1)(2, 3);
test(1)(2);
test(1)(c=3);
test(1)();
Now if I define:
def partial = test(1) _;
Then the following can be done:
partial(2, 3);
Can someone explain why I can't omit some/all arguments in 'partial' as follows:
partial(2);
partial(c=3);
partial();
Shouldn't writing "partial" behave essentially the same way as "test(1)"? Can someone please help me figure out a way to achieve this?
Please help, I'm desperate!
EDIT - Since I can't answer my own question within 24 hours, I'll post my own answer here:
This is the best I could do myself so far:
class Test2(val a: Int) {
def apply(b: Int = 2, c: Int = 3) { println(a + ", " + b + ", " + c); }
}
def test2(a: Int) = new Test2(a);
def partial2 = test2(1); // Note no underscore
test2(1)(2, 3);
test2(1)(2);
test2(1)(c=3);
test2(1)();
partial2(2, 3)
partial2(2);
partial2(c=3);
partial2();
This way it works...
The type inference engine gives to partial the type of what comes next; i.e., the eta expansion test(1) _. You can see e.g. in the REPL that partial has type (Int, Int) => Unit, whereas test has type (a: Int)(b: Int,c: Int)Unit. The result of the eta expansion is a Function object, which does not carry any argument names with it (as it is possible to define Function with anonymous parameters).
To fix this, you have to define partial as follows:
def partial(b: Int = 2, c: Int = 3) = test(1)(b,c)
Maybe you'll want to factor out the default values where both test and partial can reach them to make sure they stay equal. But I know of no trick to avoid repeating the names of the parameters without introducing extra overhead like creating of new objects, etc.
This is the best I could do myself so far:
class Test2(val a: Int) {
def apply(b: Int = 2, c: Int = 3) { println(a + ", " + b + ", " + c); }
}
def test2(a: Int) = new Test2(a);
def partial2 = test2(1); // Note no underscore
test2(1)(2, 3);
test2(1)(2);
test2(1)(c=3);
test2(1)();
partial2(2, 3)
partial2(2);
partial2(c=3);
partial2();
This way it works...
Following up on your comment, here's a more compact way to write it:
def test(a: Int) = new {
def apply(b: Int = 2, c: Int = 3) {
println(a + ", " + b + ", " + c)
}
}
This is a bit more compact than your proposal, but is less efficient, as any call to the inner apply will occur through reflection, as with structural types. Actually, the return type of test is a structural type:
java.lang.Object{def apply(b: Int,c: Int): Unit; def apply$default$1:
Int #scala.annotation.unchecked.uncheckedVariance; def apply$default$2: Int
#scala.annotation.unchecked.uncheckedVariance}