This question is so stupid... Anyway, i just can't find the right information, because every Scala-constructor example class i see works with at least one parameter.
I want to have this class translated from Java to Scala:
public class SubscriptionConverter extends Converter {
public SubscriptionConverter() {
Context ctx = new InitialContext();
UserEJB userEJB = (UserEJB) ctx.lookup("java:global/teachernews/UserEJB");
}
(...)
}
So i only have a parameterless constructor. I messed around in Scala with this(), but i couldn't get a similar example like the one above working.
How do i do i write that in Scala?
Any statements declared at the class level are executed as part of the default constructor. So you just need to do something like this:
class SubscriptionConverter extends Converter {
val ctx = new InitialContext
val userEJB = ctx.lookup("java:global/teachernews/UserEJB")
(...)
}
#dbyrne has covered the most important parts, but I'll add a few side details.
If a class has no parameters, and it's immutable, consider declare it as an object instead.
The constructor defined by statements at the class level and by parameter lists after the class name is known as the primary constructor. * Auxiliary constructors* are defined by def this() = .... Unlike Java, each auxiliary constructor must delegate to the primary constructor.
When you declare a primary constructor with zero parameter lists, the compiler will automatically add a single, empty parameter list. If you define a constructor with one implicit parameter list, the compiler will add an empty parameter list before this.
Related
I just learned about the scalar to study rocket chips.
I see some strange codes in the Config.scala of Rocket-chip
abstract class Field[T] private (val default: Option[T])
{
def this() // 1st-this
= this(None) // 2nd-this
def this(default: T) // 3rd-this
= this(Some(default)) // 4th-this
}
The above code has 4 of this. I think 2nd/4th-this are identical.
But I'm not sure 2nd/4th-this are represent Field class self-type or not.
If they are self-type, 1st/3rd-this are to be what??
I'm frustrated since I can't tell the definition of the above four this.
Could you explain this?
These are called auxiliary constructors (see https://docs.scala-lang.org/scala3/book/domain-modeling-tools.html#classes).
The "main constructor" is the one defined by the class declaration:
class Field[T] private (val default: Option[T])
With this you can create instances of Field only by passing a Option[T]. Like Field(None) or Field(Some(...)).
Then, you have 2 additional auxiliary constructors. They are defined as regular methods but they need to be called this.
The following adds a constructor that accepts no parameter so that you can create instances with Field() and it will be the same as Field(None). The 2nd this refers to the main constructor.
def this() = this(None)
Same principle for the other auxiliary constructors which allows to call Field(x) instead of Field(Some(x)).
Note that you could achieve the same with apply methods in a companion object.
I have a very basic and simple Scala question. For example, I have a java class like that
class Dataset{
private List<Record> records;
Dataset(){
records = new ArrayList<Record>()
}
public void addItem(Record r){
records.add(r)
}
}
When I try to write same class in Scala, I encoutered with some error:
class RecordSet() {
private var dataset:List[Record]
def this(){
dataset = new List[Record]
}
def addRecord(rd: Record)={
dataset :+ rd
}
}
I cannot declare a List variable like ( private var dataset:List[Record])
and cannot write a default constructor.
Here is how you will replicate the Java code you mentioned in your question:
// defining Record so the code below compiles
case class Record()
// Here is the Scala implementation
class RecordSet(private var dataset:List[Record]) {
def addRecord(rd: Record)={
dataset :+ rd
}
}
Some explanation:
In Scala, when you define a class, you have the ability to pass parameter to the class definition. eg: class Foo(num:Int, descr:String) Scala would automatically use the given parameter to create a primary constructor for you. So you can now instantiate the Foo, like so new Foo(1, "One"). This is different in Java where you have to explicitly define parameter accepting constructors.
You have to be aware that the parameter passed do not automatically become instance member of the class. Although if you want, you can tell Scala to make them instance member. There are various ways to do this, one way is to prefix the parameter with either var or val. For example class Foo(val num:Int, val descr:String) or class Foo(var num:Int, var descr:String). The difference is that with val, the instance variable are immutable. With var they are mutable.
Also, by default the instance member Scala will generate would be public. That means they can be accessed directly from an instance of the object. For example:
val foo = new Foo(1, "One")
println(foo.num) // prints 1.
If you want them to be private, you add private keyword to the definition. So that would become:
class Foo(private var num:Int, private var desc:String)
The reason why your code fails to compile is you define a method called this() which is used to create multiple constructors. (and not to create a constructor that initiates a private field which is your intention judging from the Java code you shared). You can google for multiple constructors or auxiliary constructors to learn more about this.
As dade told the issue in your code is that with this keyword you are actually creating an auxilary constructor which has some limitations like the first line of your auxilary constructor must be another constructor (auxilary/primary). Hence you cannot use such a way to create a class.
Also you can not write such lines in a scala concrete class private var dataset:List[Record] as it is considered as abstract (no definition provided).
Now with the code. Usually in Scala we don't prefer mutability because it introduces side-effects in our functions (which is not the functional way but as scala is not purely functional you can use mutability too).
In Scala way, the code should be something like this:
class RecordSet(private val dataset:List[Record]) {
def addRecord(rd: Record): RecordSet ={
new RecordSet(dataset :+ rd)
}
}
Now with the above class there is no mutability. Whenever you are adding on an element to the dataset a new instance of RecordSet is being created. Hence no mutability.
However, if you have to use the same class reference in your application use your a mutable collection for your dataset like below:
class RecordSet(private val dataset:ListBuffer[Record]) {
def addRecord(rd: Record): ListBuffer[Record] ={
dataset += rd
}
}
Above code will append the new record in the existing dataset with the same class reference.
Let's say I want an integer that supplies a square method.
Kotlin:
fun Int.square() = this * this
usage:
println("${20.square()}")
doc:
Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on variables of this type.
We would like to emphasize that extension functions are dispatched statically
My expectation would've been that they simply add it to the member functions of the extended class during compilation, but that is what they explicitly deny, so my next thought was it could be "sort of" like scala implicits.
Scala:
object IntExtensions{
implicit Class SquareableInt(i:Int){
def square = i*i
}
}
usage:
import IntExtensions._
and then
println(f"${20.square}")
doc:
An implicit class is desugared into a class and implicit method pairing, where the implciit method mimics the constructor of the class.
The generated implicit method will have the same name as the implicit class.
But scala implicits create a new class, that would disable the usage of this.
So ... how IS it that Kotlin extends classes? "Make callable" isn't telling me much.
In your case Kotlin just create simple utils-class with name "filename"Kt and static method "int square(int x)" (java pseudo-code)
From Java it look something like this
// filename int-utils.kt
final class IntUtilsKt {
public static int square(int x) {
return x * x;
}
}
And after this all calls to
val result = 20.square()
will be transformed (on byte-code level) to
val result = IntUtilsKt.square(20);
P.S.
You can see it yourself using IDEA action "Show Kotlin byte-code"
I have a case where I wish to extend a class that takes by-name parameter in it's constructor:
class Extension(something: Something)
extends Base(something.doSomething(something.getSomething(false))
class Base(expression: => Result) {
...
}
However, the call to something.getSomething(false) causes side-effects, and so can't be called multiple times.
How can I store the result of something.getSomething(false), before passing it to the superclass' constructor?
We can do this by having two constructors - one that takes both the parameter and generated parameter, and one that takes only the parameter the user should provide.
We make the first constructor private, so people don't accidentally use it, then we use the second constructor to construct the value and pass it into the first.
class Extension private (something: Something, generatedFromSomething: Generated)
extends Base(something.doSomething(generatedFromSomething) {
def this(something: Something) = this(something, something.getSomething(false))
}
As ErikAllik suggests in the comments, it may be best to simply avoid inheritance if possible, as it becomes trivial to do this outside of that case:
def extended(something: Something) = {
val generatedFromSomething = something.getSomething(false)
new Base(something.doSomething(generatedFromSomething)
}
My question is that if it is possible to overload constructors in scala?
So I can write code like:
var = new Foo(1)
var = new Foo("bar")
And if it is not possible, are there any equivalent tricks?
Sure, but there are restrictions. Scala requires that one of your constructors be "primary". The primary constructor has the special, convenient syntax of putting the constructor args right after the class name. Other "secondary" constructors may also be defined, but they need to call the primary constructor. This is different than Java, and somewhat more restrictive. It is done this way so that constructor args can be treated as fields.
Your example would look like
class Foo(myArg:String){ //primary constructor
def this(myIntArg:Int) = this(myIntArg.toString) //secondary constructor
}
val x = new Foo(1)
val y = new Foo("bar")
As you can see in Dave Griffith's example, the primary constructor must be the "most general" one in the sense that any other constructor must call it (directly and indirectly). As you can imagine, this leads sometimes to ugly primary constructors. A common strategy is to use the companion object to hide the ugliness (and you don't need to type the "new"):
class Foo private (arg:Either[String, Int]){
...
}
object Foo {
def apply(arg:String) = new Foo(Left(arg))
def apply(arg:Int) = new Foo(Right(arg))
}
val a = Foo(42)
val b = Foo("answer")
Of course you must be careful if you want to inherit from your class (e.g. this isn't possible in the example above)
class MyCons{
def this(msg:String){
this()
println(msg)
}
def this(msg1:String , msg2:String){
this()
println(msg1 +" "+msg2)
}
}
For other auxiliary constructor we must need to call primary constructor or other auxiliary defined earlier.