Constructors in Kotlin
Solution 1
Well init
is not body of constructor. It is called after primary constructor with the context of primary constructor.
As given in Official documentation:
The primary constructor cannot contain any code. Initialization code can be placed in initializer blocks, which are prefixed with the init keyword:
class Customer(name: String) {
init {
logger.info("Customer initialized with value ${name}")
}
}
Note that parameters of the primary constructor can be used in the initializer blocks. They can also be used in property initializers declared in the class body:
class Customer(name: String) {
val customerKey = name.toUpperCase()
}
In fact, for declaring properties and initializing them from the primary constructor, Kotlin has a concise syntax:
class Person(val firstName: String, val lastName: String, var age: Int) {
// ...
}
As per your question you can add a constructor to accept one parameter like following:
class Person(name: String, surname: String) {
constructor(name: String) : this(name, "") {
// constructor body
}
init {
Log.d("App", "Hello");
}
}
But it doesn't look right as we are unnecessary passing second argument empty string. So we can order constructor like following:
class Person(name: String) {
constructor(name: String, surname: String) : this(name) {
// constructor body
}
init {
Log.d("App", "Hello");
}
}
Hope it helps.
Solution 2
First way with empty values
// (name: String, surname: String) default constructor signature
class Person(name: String, surname: String) {
// init block , represents the body of default constructor
init {
Log.d("primary", "Hello");
}
// secondary constructor
// this(name,"") call to default constructor
constructor(name : String):this(name,""){
Log.d("secondary", "Hello");
}
}
why this(name,"")
If the class has a primary constructor, each secondary constructor needs to delegate to the primary constructor, either directly or indirectly through another secondary constructor(s). Delegation to another constructor of the same class is done using the this keyword:
or
kotlin won't allow to use null
like this(name,null)
so use ?
to represent null
values with type, surname: String?
class Person(name: String, surname: String?) {
init {
Log.d("primary", "Hello");
}
constructor(name : String):this(name,null){
Log.d("secondary", "Hello");
}
}
Solution 3
Inside the class use constructor
keyword to create secondary constructor. Like :
class Person(name: String, surname: String) {
init {
Log.d("App", "Hello");
}
constructor(id: Int) {
}
}
For more info check Secondary Constructors
EDIT:
Rule : If the class has a primary constructor, each secondary constructor needs to delegate to the primary constructor, either directly or indirectly through another secondary constructor(s). Delegation to another constructor of the same class is done using the this keyword.
class Person(val name: String) {
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
So when you call secondary constructor, it calls primary constructor to initialize name and after that you do your stuff in secondary constructor. In example above the name is initialized by calling primary constructor.
Solution 4
Secondary Constructors
The class can also declare secondary constructors, which are prefixed with constructor:
class Person {
constructor(parent: Person) {
parent.children.add(this)
} }
If the class has a primary constructor, each secondary constructor needs to delegate to the primary constructor, either directly or indirectly through another secondary constructor(s). Delegation to another constructor of the same class is done using the this keyword:
class Person(val name: String) {
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
} }
see https://kotlinlang.org/docs/reference/classes.html Secondary Constructors part
Solution 5
This is how you create another constructor.
class Person(name: String, surname: String) {
init {
Log.d("App", "Hello");
}
constructor(id: Int) : this("example name", "example surname") {
}
}
Always remember that, the secondary constructor will have to reference the primary constructor and it's parameters using the this keyword.
N Sharma
I have done masters in Advanced Software Engineering. I have worked on various technologies like Java, Android, Design patterns. My research area during my masters is revolving around the Recommendation algorithms that E-commerce websites are using in order to recommend the products to their customers on the basis of their preferences.
Updated on July 09, 2022Comments
-
N Sharma almost 2 years
I am learning
Kotlin
from official docs, I created oneclass
like below where I created oneconstructor
which has twoparameters
. Body ofconstructor
is ininit
block.class Person(name: String, surname: String) { init { Log.d("App", "Hello"); } }
Well, I want to create one more
constructor
which will take oneparameter
in aconstructor
. What is the way to do inKotlin
-
N Sharma almost 7 yearsI have this code
class Person(name: String, surname: String) { init { Log.d("Hello", "Hello $name $surname"); } constructor(name: String) { } }
after adding secondary constructor, Android Studio hinting meError:(10, 5) Primary constructor call expected
-
Alf Moh almost 7 yearsThis is because, you will have to call the primary constructor using the this keyword. Writing an answer soon to demonstrate.
-
N Sharma almost 7 yearsDoes
this(name)
calls primary constructor ? If so can we log to check ? -
Sachin Chandil almost 7 years
this()
is used to call constructor, its parameter signature defines which constructor to call. -
N Sharma almost 7 yearsYep correct. Can we check is it calling primary constructor or not by logging ?
-
Sachin Chandil almost 7 yearsAs given in documentation primary constructor does not have body, but you can put that code in
init
block, it should do the trick. -
Farruh Habibullaev over 5 yearsOne argument on this(name), if we consider the constructor as a special method or func, is not this(name) a return type?
-
Sachin Chandil over 5 yearsReturn type for what? Constructors does not return any value.@FarruhHabibullaev