Programming Kotlin Applications. Бретт Мак-Лахлин
Чтение книги онлайн.

Читать онлайн книгу Programming Kotlin Applications - Бретт Мак-Лахлин страница 15

Название: Programming Kotlin Applications

Автор: Бретт Мак-Лахлин

Издательство: John Wiley & Sons Limited

Жанр: Программы

Серия:

isbn: 9781119696216

isbn:

СКАЧАТЬ big help is that Kotlin is doing a lot behind the scenes. It's running code for you automatically (like that initializer block) and letting you override methods.

      It's doing something else, too: it's auto-generating some extra methods on your class. Because you made firstName and lastName property values (with that val keyword), and you defined a fullName property, Kotlin created getters and setters for all of those properties.

      Terminology Update: Getters, Setters, Mutators, Accessors

      A getter is a method that allows you to get a value. For instance, you can add this into your main function, and it will not only work, but print out just the first name of the brian Person instance:

      // Create a new person val brian = Person("Brian", "Truesby") println(brian.firstName)

      This works because you have a getter on Person for firstName. You can do the same with fullName and lastName, too. This getter is, more formally, an accessor. It provides access to a value, in this case a property of Person. And it's “free” because Kotlin creates this accessor for you.

      // Create a new person val brian = Person("Brian", "Truesby") println(brian.firstName) // Create another person val rose = Person("Rose", "Bushnell") rose.lastName = "Bushnell-Truesby"

      Just as you can get data through an accessor, you can update data through mutators.

      WARNING For the most part, I'll be calling getters accessors, and calling setters mutators. That's not as common as “getter” or “setter,” but as a good friend and editor of mine once told me, a setter is a hairy and somewhat fluffy dog; a mutator lets you update class data. The difference—and his colorful explanation—has stuck with me for 20 years.

      Now, if you've gone ahead and compiled this code, you've run into yet another odd error, and that's the last thing to fix before moving on from this initial foray into objects.

      Constants Can't Change (Sort of)

      Here's the code causing the problem:

      // Create another person val rose = Person("Rose", "Bushnell") rose.lastName = "Bushnell-Truesby"

      If you try to run this code, you'll get an error like this:

      Error: Kotlin: Val cannot be reassigned

      One of the things that is fairly unique about Kotlin is its strong stance on variables. Specifically, Kotlin allows you to not just declare the type of a variable, but also whether that variable is a mutable variable, or a constant variable.

      NOTE The terminology here is a bit confusing, so take your time. Just as with methods being declared with the fun keyword, the idea of a constant variable takes a little getting used to.

      When you declare a variable in Kotlin, you can use the keyword val, as you've already done:

      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.