1
class Person constructor(val first_name: String){ init{ println("Welcome, ${first_name}") } val last_name: String constructor(fname: String, lname: String): this(fname){ this.last_name = lname } fun fullNameGreeting(){ println("Welcome, ${first_name} ${last_name}") } } fun main() { val kotlin = "🙂" println(kotlin) val adam: Person = Person("Adam", "Kim") } 

I get following error in Kotlin Playground:-

  • Property must be initialized or be abstract
  • Val cannot be reassigned

I am just trying it after reading the documentation on Kotlin website. I am still learning but I am not able to solve this problem. Please Help.

1
  • The question you need to ask is: What does last_name get set to if you call the primary constructor directly? (Answer: it doesn't get set to anything. And that's why the compiler is complaining.) Commented Oct 3, 2022 at 8:09

3 Answers 3

1
  • Property must be initialized or be abstract:

You got this error because you didn't initialize a value to last_name, you can't just declare the name and the type of the variable, you need to assign a default value to it like that val last_name: String = ""

  • Val cannot be reassigned:

And for this error because you set last_name as a value by using val and that means that you can't change it anymore, but you are trying to change it here this.last_name = lname, so to be able to change last_name you need to set is a variable by using var, like that var last_name: String = ""

So your final code should look like this:

class Person constructor(val first_name: String){ init{ println("Welcome, ${first_name}") } var last_name: String = "" constructor(fname: String, lname: String): this(fname){ this.last_name = lname } fun fullNameGreeting(){ println("Welcome, ${first_name} ${last_name}") } } fun main() { val kotlin = "🙂" println(kotlin) val adam: Person = Person("Adam", "Kim") } 

If you want to create an instance of Person with only first_name or both first_name and last_name, you can use this approach:

class Person constructor( val first_name: String, val last_name: String = "" ){ init{ println("Welcome, ${first_name}") } fun fullNameGreeting(){ println("Welcome, ${first_name} ${last_name}") } } 

This way you can either call Person("Your first name"), or Person("Your first name", "Your last name")

Sign up to request clarification or add additional context in comments.

2 Comments

So this means I can't use constants member with secondary constructors? like I have used with primary constructor.
You can but it's quite different in kotlin, I will add how you can achieve that
1

I'd suggest switching the constructors around. Then you can do

class Person constructor(val first_name: String, val last_name: String){ init{ println("Welcome, ${first_name}") } constructor(fname: String): this(fname, "") fun fullNameGreeting(){ println("Welcome, ${first_name} ${last_name}") } } 

or better yet, make the second parameter optional, like

class Person constructor(val first_name: String, val last_name: String = ""){ init{ println("Welcome, ${first_name}") } fun fullNameGreeting(){ println("Welcome, ${first_name} ${last_name}") } } 

Comments

0

It seems that val is used for constant and var for variable (overwritable) properties. If you replace vals in the class with vars, it works.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.