Gideon Sassoon
Gideon Sassoon

Reputation: 604

Kotlin data class with additional properties not in constructor

Starting out with Kotlin and wanting to make a data class

data class Person(val Email: String, val firstName: String, val lastName: String)

But let's say I want to add additional properties that I don't know at the time when I am using the constructor but I want to store this data at a later point when I am aware of it for example a person's mood (Represented as a String)

In Java I would make a data class like this. I would be able to not include it in the Constructor and make a getter where I could set it at a later time.

public class Person{

     private String email;
     private String firstName;
     private String lastName;
     private String mood;

     public person (String email, String firstName, String lastName){
      this.email = email;
      this.firstName = firstName;
      this.lastName = lastName;
    } 

    public setMood(String mood){
     this.mood = mood;
    }
}

Kotlin doesn't appear to have an answer on this or if it does I do not know how to phrase correctly. Hence why this question could already be answered and I am unable to find it.

I do understand that by not including mood in the data class line Kotlin may not be able to identify mood as part of the data class but aside from including it in the constructor and setting it to null I'm not sure what else to do or is that what I am supposed to do?

Upvotes: 5

Views: 7537

Answers (5)

Alexey Romanov
Alexey Romanov

Reputation: 170723

An alternative to @Todd's and @jingx's answers is

data class Person(val Email: String, val firstName: String, val lastName: String, var mood: String? = null)

The difference is that this way mood participates in toString/equals/hashCode/copy and that you can set mood in the constructor call. Even if that's probably not desirable for this specific case, it can be useful in others.

Upvotes: 3

CryptoFool
CryptoFool

Reputation: 23079

Kotlin only considers the values passed to the primary constructor in terms of giving you the "for free" features that a Data class provides. Beyond that, you can add whatever additional properties you desire, but they aren't accounted for in the special code that Kotlin writes by way of you marking a class as data.

Per the Kotlin docs:

Note that the compiler only uses the properties defined inside the primary constructor for the automatically generated functions. To exclude a property from the generated implementations, declare it inside the class body:

Per this, declaring properties outside of the primary constructor actually has benefits. You might be able to declare a property via the primary constructor, but choose not to.

Not only do you have to provide a primary constructor, but it has to include at least one property declaration. If you didn't do this, there would be no benefit to making the class a data class. But marking a class so does not limit what else you can do with that class.

Upvotes: 5

jingx
jingx

Reputation: 4014

Have you tried:

data class Person(val Email: String, val firstName: String, val lastName: String) {
    var mood: String? = null
}

Upvotes: 2

Fima Taf
Fima Taf

Reputation: 977

Kotlin's data class must have first constructor, you can avoid it by not using the data keyword.

If you still want to add another property to the data class you can do the following:

data class Person(val email: String, val firstName: String, val lastName: String){
    var mood: String = ""
}

This way you can do person.mood = "happy" without including it in the constructor.

Upvotes: 3

Todd
Todd

Reputation: 31660

You should be able to just add it as a property to Person. In Kotlin, a data class is still a class, it just comes with some extras (toString, copy constructors, hashCode/equals, etc). You can still define any properties that you want.

data class Person(val Email: String, val firstName: String, val lastName: String) {
    var mood: String? = null
}

In this case it is nullable, because as you stated, you might not know the mood until later.

Upvotes: 12

Related Questions