Скачать книгу

      val brian = Person("Brian", "Truesby")

      var brian = Person("Brian", "Truesby")

      First, in both cases, you end up with a variable; val does not stand for value, for example, but is simply another way to declare a variable, alongside var. When you use val, you are creating a constant variable. In Kotlin, a constant variable can be assigned a value once, and only once. That variable is then constant and can never be changed.

      You created the lastName variable in Person with this line:

      class Person(val firstName: String, val lastName: String) {

      That defines lastName (and firstName) as a constant variable. Once it's passed in and assigned when the Person instance is created, it can't be changed. That makes this statement illegal:

      rose.lastName = "Bushnell-Truesby"

      To clear up the odd error from earlier, what you need instead is for lastName to be a mutable variable; you need it to be changeable after initial assignment.

      NOTE Not to beat a hairy and somewhat fluffy dog to death, but here is another reason to use mutator over setter; a mutator allows you to mutate a mutable variable. This aligns the terminology much more cleanly than using “setter.”

      So change your Person constructor to use var instead of val. This indicates that firstName and lastName can be changed:

      class Person(var firstName: String, var lastName: String) {

      Here, fullName has been made mutable, and there's a little more printing in main. It should compile and run without error now.

      But wait! Did you see your output? There's a problem! Here's what you probably get when you run your code:

      Brian Truesby Rose Bushnell Rose Bushnell

      Despite what Meat Loaf had to say about two out of three not being bad, this is not great. Why is Rose's name in the last instance not printing with her new last name?

      Well, to solve that, it's going to take another chapter, and looking a lot more closely at how Kotlin handles data, types, and more of that automatically running code.

      WHAT'S IN THIS CHAPTER?

       Dive deeper into Kotlin types and variables

       More on mutability

       Creating custom accessors and mutators

       Assignment, during and after variable creation

       Type safety and what it means

      You've already had a solid introduction to Kotlin, including building your first object. So we're going to get right to work. There's that nagging issue with a person's last name showing incorrectly, but before fixing that, you're ready to up how you build classes from a pre-compile point of view.

      So far, you've used a single file to contain both your class ( Person) and your main function. That's not scalable, though. Before long, you're going to have lots of classes—and that's classes, not instances of classes.

      NOTE As a quick refresher, a class is a definition. You have a Person class, and you might also have a Car class or a House class. An instance of a class is a specific piece of memory that holds a representation of an object. In the last chapter, when you created a brian or a rose variable, you assigned those instances of the Person class.

       It's pretty easy to get lots of instances of a class, and then to also have lots of different classes defined as well. In those cases, things get messy if you're just using a single file.

      Name a File According to Its Class

      class Person(var firstName: String, var lastName: String) { var fullName: String // Set the full name when creating an instance init { fullName = "$firstName $lastName" } override fun toString(): String { return fullName } }

      fun main() { // Create a new person val brian = Person("Brian", "Truesby") println(brian) // Create another person val rose = Person("Rose", "Bushnell") println(rose) // Change Rose's last name rose.lastName = "Bushnell-Truesby" println(rose) }

Скачать книгу