19.0512

パッケージ / package(キーワード)

package(パッケージ) とは、
  class や 関数 を、ユニーク なものにするための方法
ユニーク なものとは、
  唯一のもの、全世界に一つしかないもの
    / ただし、プログラミング の、練習のためには、そこまではしないのが普通でしょう。
どんな方法かを、簡単に言うと、
  例えば、とてもたくさんいると思われる 田中さん を、特定するためには、
    住所、名前(苗字ではなく)
ここまで、条件を付ければ、唯一の、田中さんを特定できると思います。
(ここで、真剣に、細かく考えないでください、、あくまで、理解するための例なので.)
(例えば、同姓同名 の、田中さんが同じ家に住んでいることはあり得ますが.)


1. Kotlin での package の 文法
まずは、文法的な視点 で、見ていきます。
こんな class 3つ と それらのclassのメソッド を実行する ファイル を、作りました。

ここで、注意して見てほしいのは、これら3つのファイル
  すべて、Carクラス
  すべての メソッド名 は id()
ということです。

ですが、
  一番下のファイル
    TestPackage.kt
では、
  きっちり、この3つの class と メソッド を区別して
います。

どのようにして区別しているのか?
  各上の3つファイル の、先頭部分 に、
    package num1
    package num2
    package num3

と書いてあるのが、分かると思います。

さらに、TestPackage.kt で、
  各 Carクラス の、インスタンス
    number1
    number2
    number3

を、作成する時、
    val number1 = num1.Car()
    val number2 = num2.Car()
    val number3 = num3.Car()
として、作成しています。

そうです、
  1. ファイルに、
      package whatwhat(パッケージ なになに)
    を、書く
  2. クラス や 関数(classに属していない時) に、アクセスする時
      whatwhat.AruClass()(あるパッケージ.あるclass())
    で、アクセスする
(インスタンス化 する場合)
ということです。

そして、コンソール画面では、それぞれのclass から、メソッドを呼び出した結果 が、表示されています。


同名の関数 を区別する
今度は、
  class に属していない 関数 を、区別する
場合について見ていきましょう。

これも、基本的に、先ほどのやり方と同じです。
具体的には、こんなコード になります
これも、先ほどと同様に、
  package名 を、使って、関数 aruFun() を、特定
していますね。


2. package名 に関する、文法 以下 慣習 以上
先ほどの、package名 では、
こんなサンプルプログラム では、OK ですが、
実用性は、ありません。
なぜなら、
  package num1
などは、全く同じ名前の、package名 が、使われる可能性は、あり過ぎます。

そこで、こんなルールを使って、ユニークな/唯一の package名 に、なるようにしています。
  ドメイン を、./ドット 区切りで、逆さに並べる
ドメイン名 とは、Webサイトの、ホームページアドレス のことです。
例えば、

  グーグル の場合:   com.google
となります。
(もともとのドメインは、google.com
ここで、https://www
は、どうなっているのか?、とお思いかもしれませんが、
  https:// や http://(スキーム)
  www(ホスト名)
という名前で呼ばれています。
詳しいことは、ここでは省略します(お知りになりたい方は、検索してください)。
これは、先ほどの、
  package num1
でも、うまく動作したように、文法 ではないです、、、が、、、
  「お約束」(文法以下、慣習以上 と言えるでしょう)
になっています。

そして、それに続けて、ユニークな、名前を付ければいいのです。
例えば、
  guruguru.com という ドメイン があるとしたら、
    package com.guruguru.car
などとなるでしょう。


フォルダへの配置方法
と、言っておきながら、それに関するルール は、Kotlin の場合、特に決められてはいませんが、
(そうはいっても、アクセスするためには、細かく分けなくても、同じフォルダ に、置くと思われる)
先ほどのpackage com.guruguru.car であれば、
  フォルダで分けの決まりがある、Java のやり方をまねると、
    まず、src(ソースコード/コンパイル前のコード/src フォルダ)
      そして、com
        その中に、guruguru
          またまたその中に、car
  つまり、src\com\guruguru\car\Car.kt
な風に、整理しています。
これは、良い方法の一つですが、
これに関しては、例えば、IntelliJなどに、配置は任せれば、いいと思います。
それなりの大きなプログラムが、出来たら、ゆっくり調べても遅くはないでしょう。

IntelliJ の、配置方法 について調べました: ●作ったファイル   Car.ktpackage car)   Jeep.ktpackage car.jeep)      ソースファイル(Car.kt と Jeep.kt)     ProjectName\src\Car.kt     ProjectName\src\Jeep.kt       // ProjectName:プロジェクトの名前          classファイル(Car.class, Carkt.class, Jeep.class, JeepKt.class)       // classファイル とは、コンパイルして出来上がった、ファイル。     ProjectName\out\production\ProjectName\car\Car.class     ProjectName\out\production\ProjectName\car\CarKt.class     ProjectName\out\production\ProjectName\car\jeep\Jeep.class     ProjectName\out\production\ProjectName\car\jeep\JeepKt.class
ソースファイル/~.kt に関しては、同じフォルダに置かれ、
classファイル(コンパイル後のファイル)は、だいたい、Java風 だと思われます。

これを見て思うのは、まあ、私は、IntelliJ先生に、お任せしようと思いました。


3. import文 を使えば、package名 は、1回書くだけ
これで、
  目的の、class や 関数 に、アクセスする方法
は、解決しました。

でも、普通は、パッケージ名は、もっと長いのが普通です。
だとすると、
  先ほどのやり方では、使いたい class や 関数 が登場するたびに、
  package名 を、書かなければならない
という事になってしまいます。

ですから、普通は、
  import文
を、使います。

ここで、
  package名 で、個別に一つ一つ 特定する場合 と、
  import文 で、まとめて、「パッケージ名を書くことを省略する場合」
を、比べるために、こんなコード で、比べました

左側のコードでは、
  Animalクラス を、使うために、
    2回、one.two.three.animal.
を、使って、アクセスしていますが、
右側のコードでは、
  import one.two.three.animal.Animal
を、1回書いて、
  Animalクラス を、特定する時は、
    one.two.three.animal.
  を、省略できるので、
  何も前に付けずに、
  Animal
だけで、アクセスできています。

import文の 構文:
  import パッケージ名
です。

また、one.two.three.animal 以下に、
  one.two.three.animal.dog
  one.two.three.animal.cat
  one.two.three.animal.fox
などと、複数の、package がある場合、
まとめて、
  import one.two.three.animal.*
のように、
  */アスタリスク
を、使うことが出来ます。


4. どうして、println() は、import文無し で、使えるのか?
それは、
  デフォルトで、すでに、import されている
  (暗黙でimportされている/書かなくても使える)
からです。

次の package は、デフォルトで、import されています。

kotlin.* kotlin.annotation.* kotlin.collections.* kotlin.comparisons.* (ver 1.1 より) kotlin.io.* kotlin.ranges.* kotlin.sequences.* kotlin.text.*
これに関する、リファレンス は、このページ です。

そして、
  println()関数 は、「Kotlin.io」パッケージ に、所属しています。
ですから、println() を、省略せずに呼び出すコード は、こうなります。

fun main() { kotlin.io.println("println()関数 は、Kotlin.io パッケージ に、あります") }
普通は、こんな書き方はしませんが、このコードを、書いて実行してみると、
package について、より理解できるでしょう。


5. Java の ライブラリ を、import する
残念ながら、私は、Javaのたくさんのライブラリの使い方に関しては、全然知りません。
ここでは、
  使い方
に絞って、見ていきましょう。


Math.random()メソッド を、Kotlin で、使う
Java のクラスライブラリにある
  Math.random()メソッド
     (0.0以上で1.0より小さい、正の符号の付いた Double の、乱数 を、返す)
    / なんで、Math が、大文字始まり なのかは、
    / Java には、class名 で呼び出す、staticメソッド があるからです.
    / 今は、そんなものかで、いいと思います。
    / Kotlin にも、代替え方法 として、「companion object」
    / を、使う方法が、あるようです。
は、package名 も含めて書くと、
  java.lang.Math.random()メソッド
と、なります。

そこで、今までのルールに従って、
こんなコードを書きました

Java の、ライブラリ を、import する場合も、基本的なルールは、同じです。

ただ、
  java.lang.*
は、デフォルトで、import されており
  本当は、書く必要は、ありません。
こんなコードでも、コンパイルできます
まあでも、「使い方」 に関しては、理解できたと思います。



まとめ
package(パッケージ) とは、class や 関数 を、ユニーク なものにするための方法です。
package の使い方
  1. ファイルに、
      package whatwhat(パッケージ なになに)
    を、書く
  2. クラス や 関数(classに属していない時) に、アクセスする時
      whatwhat.AruClass()(あるパッケージ.あるclass())
    で、アクセスする
(インスタンス化 する場合)
・ 同名の関数(classに属していない)に、アクセスする場合も、やり方は、同様です。
・ package名 に関する、文法以下、慣習以上:
   ドメイン を、./ドット 区切りで、逆さに並べる
・ フォルダへの配置方法: まあ、私は、IntelliJ先生 に、お任せします。
import文 を、使うと、書く労力 を、削減できます。
   import文の 構文:
     import パッケージ名
・ Kotlin では、デフォルトで、import されている package があるので、
 それに関しては、import文 は、不要です。
   / println()関数 など
Java の、ライブラリ を、import する場合も、基本的なルールは、同じです。
java.lang.* パッケージ は、デフォルトで、import されており、書く必要は、ありません。