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

Чтение книги онлайн.

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

Programming Kotlin Applications - Бретт Мак-Лахлин

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

href="#ulink_b592c4bc-4aa8-5e34-84be-c8ac830209dd">Figure 1.10.

Snapshot of why doesn't this override of toString() work?

      What gives here? Well, it turns out to be a little tricky.

      All Data Is Not a Property Value

      You have a constructor and it takes in two pieces of data: firstName and lastName. That's controlled by the constructor declaration:

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

      You need to use the val keyword in front of each piece of data to turn that data into property values. Here's the change you need to make:

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

      Specifically, by using val (or var, which we'll talk about shortly), you've created variables, and assigned them to the Person instance being created. That then allows those variables (or properties, to be even more precise) to be accessed, like in your toString() method.

      class Person(val firstName: String, val lastName: String) { override fun toString(): String { return "$firstName $lastName" } } fun main() { val brian = Person("Brian", "Truesby") println(brian) }

      You should get a single line of output:

      Brian Truesby

      Obviously, the name will be different if you passed in different values for first and last name, but the result is the same, and it's a big deal. You've now:

       Created a new object

       Defined a constructor for the object

       Accepted two pieces of data in that constructor and stored them as properties associated with the object instance

       Overridden a method and made it useful

       Written a main function

       Instantiated your custom object and passed in values

       Used the object to print itself out, using your overridden method

      class Person(val firstName: String, val lastName: String) { val 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") // Create another person val rose = Person("Rose", "Bushnell") println(brian) }

      You'll see a number of new things here, but none are too surprising. First, a new variable is declared inside the Person object: fullName. This is something you've already done in your main function. This time, though, because you're doing it inside the Person object, it automatically becomes part of each Person instance.

      Another small change is the addition of a new Person instance in main ; this time it's a variable named rose.

      Then, there's a new keyword: init. That bears further discussion.

      Initialize a Class with a Block

      In most programming languages, Java included, a constructor takes in values (as it does in your Person class) and perhaps does some basic logic. Kotlin does this a bit differently; it introduces the idea of an initializer block. It's this block—identified conveniently with the init keyword—where you put code that should run every time an object is created.

      In this case, the initializer block uses the new fullName variable and sets it using the first and last name properties passed in through the class constructor:

       // Set the full name when creating an instance init { fullName = "$firstName $lastName" } Then this new variable is used in toString(): override fun toString(): String { return fullName }

      WARNING As much new material as this chapter introduces, you may have just run across the most important thing that you may learn, in the long-term sense. By changing toString() to use fullName, rather than also using the firstName and lastName variables directly, you are implementing a principle called DRY: Don't Repeat Yourself.

       In this case, you're not repeating the combination of first name and last name, which was done already in the initializer block. You assign that combination to a variable, and then forever more, you should use that variable instead of what it actually references. More on this later, but take note here: this is a big deal!

      Kotlin Auto-Generates Getters and Setters

      At this point, things are going well. Part of that is all

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