只今javaをコツコツと某参考者を読みながら勉強しているのですが、importの部分で自分の考えが混乱していて今現在頭の中にある考えが正しいかどうか教えてください。
正確に言いますと、packageとimportについてですね・・・
{私の考え}
複数のファイルに分けて比較的大きなプログラムにするとき、「package パッケージ名」で定義してあげれば同じパッケージ内であれば違うファイルに作ったクラスを利用できますよね・・
しかし、例えば、2つのパッケージがあり、それぞれの中に別ファイルで作成したクラスが20個あるとすると、一々すべてのクラスにpackage ○○ と書くのはめんどくさいのでimportを使う(結構大雑把な書き方(私の文章が))
と、かいてありました。
これは、パッケージを用意するときもそうなのですが必ずパッケージ名と同じ名前のディレクトリを用意しますよね・・・その中にクラスのファイルを入れる・・・
ここで、importはこの場合20個作成したクラスのファイルの先頭にpackage ○○と書かなくてもそのパッケージのディレクトリに入れれば、新しく作られた(例として)Mainファイルのコードの上に「import パッケージ名.クラス名」と記述すればそのディレクトリ(パッケージ)の中の指定したクラスを利用できる(public class ○○にしてですが)ということでいいのでしょうか?そして、パッケージ内のすべてのクラスを使いたい場合は「import パッケージ名*」とすればいいということ・・・ですよね・・・・
私の考えは正しいでしょうか?
こまかな違いでも見つけましたらご指摘ください。
読みにくい文章ですいません。
それと、この分野に関して豆知識などありましたら教えてください。
javaのimportについて質問があります
Re: javaのimportについて質問があります
packageはclassファイルを作るときに意味を持つものです。
package文はパッケージに属するソースファイルすべてに記述しなければいけません(省略できません)。
classファイルの配置されるディレクトリ構造とも一致していなければいけません。
パッケージはアクセス指定とも関連しているのでアクセス指定子の意味もいっしょに調べてみてください。
importはclassファイルを利用するときに意味を持つものです。
完全修飾名からパッケージ名を省略できるようにするためのもので、pachage文とは関係ありません。
例えば、import文を使うとこのように書けますが… import文を使わないとこのように書く必要があります。 どこが違ってどう便利なのか分かりますか?
package文はパッケージに属するソースファイルすべてに記述しなければいけません(省略できません)。
classファイルの配置されるディレクトリ構造とも一致していなければいけません。
パッケージはアクセス指定とも関連しているのでアクセス指定子の意味もいっしょに調べてみてください。
importはclassファイルを利用するときに意味を持つものです。
完全修飾名からパッケージ名を省略できるようにするためのもので、pachage文とは関係ありません。
例えば、import文を使うとこのように書けますが… import文を使わないとこのように書く必要があります。 どこが違ってどう便利なのか分かりますか?
Re: javaのimportについて質問があります
ふむ・・・
packageはクラスの継承や拡張に使い、importは完成されたclass(型)を利用して組み合わせていく(数値などの代入や、Main関数)ときに使うということ・・・ですか?
そして、二つのコードを見比べるとextendsの後が違いますよね・・
importで指定?すれば新たなオブジェクトを作るときとかもパッケージ名を省略できて見やすいし楽ということですよね?
packageはクラスの継承や拡張に使い、importは完成されたclass(型)を利用して組み合わせていく(数値などの代入や、Main関数)ときに使うということ・・・ですか?
そして、二つのコードを見比べるとextendsの後が違いますよね・・
importで指定?すれば新たなオブジェクトを作るときとかもパッケージ名を省略できて見やすいし楽ということですよね?
Re: javaのimportについて質問があります
そんなに難しい理由ではありません。
例えばこんなクラスを作るとします。 このクラスの完全修飾名はfoo.bar.Hogeです。
他のクラスからこのクラスを参照するときはこの名前を使います。
Hogeより前に付くのがパッケージ名で、極端に言えばただクラス名の前に付くだけのシロモノです。
ただし名前としては重要でパッケージ名も含めて区別されます。
ここは難しい話になりますが、Javaでprivate以外のアクセス指定子は、同一パッケージ内では常に公開となります。
そのため、外部に対してアクセス制御を厳しくしても、同一パッケージ内部では緩くなります。
#逆に言えば外部に対して積極的に厳しくできます。
必然的に同一パッケージにまとめるクラスは密接に関連していなければいけないことになります。
foo.bar.Hogeを使うときは、すべての宣言場所でfoo.bar.Hogeという型を使う必要があります。
しかし、他にHogeという名前を使っておらずHogeだけで区別できるのに、何度もいちいちfoo.bar.Hogeと書くのは面倒くさいというとき、
import foo.bar.Hoge;
と書いておけばHogeはfoo.bar.Hogeのことだと読み替えてくれる、ただそれだけのものです。
簡単にまとめると…
package宣言されるパッケージは関連性の高いクラスをまとめる単位として使用され、名前の一部になる。アクセス制御に特例がある。
import宣言は、完全修飾名からパッケージ名の部分を省略するための読み替えの指示。
です。
パッケージが同じでも違っても継承は可能ですよ。
例えばこんなクラスを作るとします。 このクラスの完全修飾名はfoo.bar.Hogeです。
他のクラスからこのクラスを参照するときはこの名前を使います。
Hogeより前に付くのがパッケージ名で、極端に言えばただクラス名の前に付くだけのシロモノです。
ただし名前としては重要でパッケージ名も含めて区別されます。
ここは難しい話になりますが、Javaでprivate以外のアクセス指定子は、同一パッケージ内では常に公開となります。
そのため、外部に対してアクセス制御を厳しくしても、同一パッケージ内部では緩くなります。
#逆に言えば外部に対して積極的に厳しくできます。
必然的に同一パッケージにまとめるクラスは密接に関連していなければいけないことになります。
foo.bar.Hogeを使うときは、すべての宣言場所でfoo.bar.Hogeという型を使う必要があります。
しかし、他にHogeという名前を使っておらずHogeだけで区別できるのに、何度もいちいちfoo.bar.Hogeと書くのは面倒くさいというとき、
import foo.bar.Hoge;
と書いておけばHogeはfoo.bar.Hogeのことだと読み替えてくれる、ただそれだけのものです。
簡単にまとめると…
package宣言されるパッケージは関連性の高いクラスをまとめる単位として使用され、名前の一部になる。アクセス制御に特例がある。
import宣言は、完全修飾名からパッケージ名の部分を省略するための読み替えの指示。
です。
クラスの継承や拡張でパッケージ(名)がどういう役割というか使われ方をするとイメージしてます?mi_l さんが書きました:packageはクラスの継承や拡張に使い、importは完成されたclass(型)を利用して組み合わせていく(数値などの代入や、Main関数)ときに使うということ・・・ですか?
パッケージが同じでも違っても継承は可能ですよ。
「新たなオブジェクトを作るとき」というのが宣言時の型を指しているのであればそういうことですね。mi_l さんが書きました:importで指定?すれば新たなオブジェクトを作るときとかもパッケージ名を省略できて見やすいし楽ということですよね?
Re: javaのimportについて質問があります
importはC++での「using namespace」と同じで名前空間を省略できるプリプロセッサです
Re: javaのimportについて質問があります
なるほど!!
関連のある(高い)クラスをまとめるときはpackage、しかし、パッケージでまとめるのはいいけどこのままでは他のクラスから参照するときに完全修飾名を何回も一々書かなければいけない・・ここでimportしてあげるとその手間が省けると・・・いうことですよね。
関連のある(高い)クラスをまとめるときはpackage、しかし、パッケージでまとめるのはいいけどこのままでは他のクラスから参照するときに完全修飾名を何回も一々書かなければいけない・・ここでimportしてあげるとその手間が省けると・・・いうことですよね。
Re: javaのimportについて質問があります
パッケージは関連のあるクラスをまとめる他に,名前空間の分離という役割もあります。
完全修飾名が一意であればクラス名は同一でも良いので,java.util.Dateとjava.sql.Dateのようにパッケージを除くクラス名が同じものも存在します。
標準ライブラリでこれはどうなの,とは思いますが,同じ目的の異なる複数のライブラリで同じクラス名になることは容易に想像が付きます。
e.g.) org.codehaus.jackson.JsonFactory / com.google.api.client.json.JsonFactory
なので,これをパッケージを使って分離している側面もあります。
このため,デフォルトパッケージは少なくともライブラリでは使われません。
パッケージ名は,「保持している(トップレベル)ドメイン or メールアドレスを逆向き (e.g. net.dixq, com.example.foo) に使って,その後ろに本来の意味でのパッケージ名を付ける」が基本です。
# sun/oracleの規約,1999年Updateって……。大きなところでもJava 5のGenericsがあったと言うのに……。
完全修飾名の記述自体は,今となってはIDEの補完機能でできるのであまり手間ではなかったりしますが,あまりに何度も出てくるクラスが完全修飾名だと読みにくくなるため,importした方がよくなります。
逆に,Factoryクラスなどで1度しか出てこない上に戻り値を別パッケージのインターフェースで受けるような場合は,完全修飾名で書いてしまった方が読みやすく/わかりやすくなったりします。
# importで*を使うと,IDEなしの環境下でクラスのパッケージを探すのに苦労するので,使わないことを推奨。
完全修飾名が一意であればクラス名は同一でも良いので,java.util.Dateとjava.sql.Dateのようにパッケージを除くクラス名が同じものも存在します。
標準ライブラリでこれはどうなの,とは思いますが,同じ目的の異なる複数のライブラリで同じクラス名になることは容易に想像が付きます。
e.g.) org.codehaus.jackson.JsonFactory / com.google.api.client.json.JsonFactory
なので,これをパッケージを使って分離している側面もあります。
このため,デフォルトパッケージは少なくともライブラリでは使われません。
パッケージ名は,「保持している(トップレベル)ドメイン or メールアドレスを逆向き (e.g. net.dixq, com.example.foo) に使って,その後ろに本来の意味でのパッケージ名を付ける」が基本です。
# sun/oracleの規約,1999年Updateって……。大きなところでもJava 5のGenericsがあったと言うのに……。
完全修飾名の記述自体は,今となってはIDEの補完機能でできるのであまり手間ではなかったりしますが,あまりに何度も出てくるクラスが完全修飾名だと読みにくくなるため,importした方がよくなります。
逆に,Factoryクラスなどで1度しか出てこない上に戻り値を別パッケージのインターフェースで受けるような場合は,完全修飾名で書いてしまった方が読みやすく/わかりやすくなったりします。
# importで*を使うと,IDEなしの環境下でクラスのパッケージを探すのに苦労するので,使わないことを推奨。
Re: javaのimportについて質問があります
完全修飾名を使わないことには、import文を書き換えるだけでライブラリをすげ替えることができるというメリットもあります。
ガラケーアプリの開発では、キャリアごとに仕様が異なっている部分をラッパ(wrapper)ライブラリで置き換えることがよくありました。
ガラケーアプリの開発では、キャリアごとに仕様が異なっている部分をラッパ(wrapper)ライブラリで置き換えることがよくありました。