Programming Kotlin Applications. Бретт Мак-Лахлин
1. Your output should also be the same. You can see in Figure 2.1 the IntelliJ IDE, with the two Kotlin files as tabs, and the output in the bottom pane.
FIGURE 2.1 Your IDE should let you easily get to your source code as well as see output.
WARNING If you get any warnings, the most likely culprit is that you didn't create your Person
and PersonApp
files in the same directory. Make sure both files are in the src/
directory and try again.
At this point, you could go ahead and keep creating more objects in the src/
directory. But there's still a better way!
Organize Your Classes with Packages
While it's great that you've got Person
separate from the test main
function, you've still not really solved the original problem: class organization. If having all your classes in one file is a pain, then by extension, so is having all your classes in a single directory.
What you really want is to organize your classes by functionality. So let's assume that you want your Person
class, but you also think you might later want some specific types of people; maybe a Mother
class or a Child
class. Suppose you're building software to model a genealogy, for example.
In that situation, you really want your classes related to Person
grouped together. But you might also have some classes related to the customer, with their account information: username, password, email. These aren't instances of Person
, they're (perhaps) instances of a User
. You might even have a UserPreferences
class at some point, too, letting you store that user's information. So that might all belong to a group of classes related to User
.
Kotlin—and many other languages—use the concept of packages to provide this organization. A package is just a logical grouping of classes, with a particular namespace: some way to prefix and identify classes as being related. You could have a person
package with Person
, Mother
, Father
, and so forth, and a user
package with User
, UserPreferences
, and the like.
Naming your package is important, though, so a few best practices:
Packages should begin with lowercase letters. Use person instead of Person. (Classes begin with capitals; packages with lowercase.)
Start the package with a dot-separated name that identifies the organization, like org.wiley or com.myCodeShop.
If you might use languages other than Kotlin, you may want to also add kotlin as part of the package name, to distinguish the package from other code (such as Java).
Put all this together and separate the pieces with a dot delimiter (.). For this book, the package will usually be org.wiley.kotlin.[general category]
. Person
will be in org.wiley.kotlin.person
and User
will be in org.wiley.kotlin.user
.
NOTE You don't always have to have the last part of the package name (like person
) match a class in that package (like Person
). You might have an org.wiley.kotlin.sport
package that has various sports-related classes like Football
, Baseball
, Hockey
, and Volleyball
, but not have an actual Sport
class. It really depends on your own preferences and style.
Put Person in a Package
With a package decided, you need to actually create this structure. Again, this is where an IDE can really make things simpler. If you're using IntelliJ, right-click your src/
folder and choose New and then Package. Type in the package name ( org.kotlin.wiley.person
if you're following along, or use your own name), and you'll see a small package indicator created as part of your src/
tree.
WARNING Each IDE handles this a bit differently, but the similarities are far greater than the differences. You can always just play around with the IDE to look for a New Package option (that's what I did when I was first learning Kotlin in IntelliJ), or check your IDE's documentation.
If you're using the command line exclusively, it's a bit more of a pain. You'll need to create a directory structure to match your package structure, so you'd need an org/
directory, and then wiley/
, then kotlin/
, then person/
, and then put your Person
class there. You'll also need to work with the kotlinc
compiler a bit more.
You can find this documentation easily online, so to keep things moving, most of this book will assume you're either using an IDE or comfortable looking up how to compile files in packages on your own.
Now comes the “thank goodness for an IDE” part: just click your Person
class in the left pane and drag it into the new package indicator. You'll get a dialog box that looks like Figure 2.2.
FIGURE 2.2 Moving a class to a new package is basically a refactoring, which your IDE can handle.
This dialog will ensure that yes, you really do want to move the class into the indicated package. You can leave all these defaults, as IntelliJ is happy to do this work for you. When you're ready, click the Refactor button.
Now, your navigation pane (on the left in the IDE) should show Person
under the new org.wiley.kotlin.person
package, as shown in Figure 2.3.
Before you think that too much magic has gone on, take a close look at the first line of your Person
class, which is new:
package org.wiley.kotlin.person
That line tells Kotlin that the class belongs to the org.kotlin.wiley.person
package. The compiled class then actually is org.kotlin.wiley.person.Person
, not just Person
.
This is going to cause your main
function to break, because that function doesn't know anything about org.kotlin.wiley.person.Person
; and now there's no Person
class.
FIGURE 2.3 Person is now nested under its containing package.
WARNING This is a great example of a very small detail having a very big effect on your code. A class without a package, and a class within a package, are not the same at all—even if they are named the same. You could theoretically have multiple classes named the same in multiple packages, and each is distinct from the other. Hopefully you're already thinking this is a bad idea; but it