明解Java入門編 第15章まとめ
文字
文字は整数値のコードで表され識別される。
文字コードには種類があり、Javaが採用しているのはUnicodeである。
Unicode
・全ての文字に固有の番号を与える
・プラットフォームに依存しない
・プログラムに依存しない
・言語に依存しない
char型
文字を表す。
中身が空である""が許される文字列リテラルとは異なり、中身が空である文字リテラル''はコンパイルエラーになる。
文字列と文字列リテラル
文字列リテラルはString型インスタンスへの参照である。
文字列はString型である。
文字列の代入は文字列のコピーでなく参照のコピーである。
Stringクラスは文字列を格納するためのchar型の配列などのフィールドと数多くのコンストラクタおよびメソッドを有している。
キーボードからの読み込み
Scannerクラスのnextメソッドとnextlineメソッドは、キーボードから読み込んだ文字列を内部に持つString型インスタンスを生成してそのインスタンスへの参照を返却する。
コマンドライン引数
プログラム起動時にコマンドラインから与えられた文字列の配列はmainメソッドの引数として受け取ることができる。
明解Java入門編 第14章まとめ
インターフェース
インターフェースのメソッドはpublicかつabstractである。それを実装するクラスではメソッドにpublic修飾子を与えて実装する。
インターフェース型のインスタンスを生成することはできない。
インターフェース型の変数は実装クラスのインスタンスを参照できる。
実装するインターフェースの全メソッドを実装しないクラスは、抽象クラスとして宣言する必要が有る。
メンバとして定数を持つことができるが定数でないフィールドを持つことはできない。
インターフェースで宣言されたフィールドは、public static finalとなり、値を書き換えることのできないクラス変数になる。
インターフェースの名前は原則として名詞。振る舞いを表現する形容詞としてもよい。
インターフェース宣言
先頭のキーワードがclassではなくinterfaceとなる。
メソッド本体{...}の代わりに;をつけて宣言する。
インターフェース実装
インターフェース内で宣言された抽象メソッドの実体はインターフェースを実装するクラスの中で定義する。用いるキーワードはimplements。
インターフェースのメソッドはpublicかつabstractである。それを実装するクラスではメソッドにpublic修飾子を与えて実装する。
クラス派生とインターフェースの実装
extendsとimplementsの両方がある場合、必ずextendsを先にかかなければならない。
複数インターフェースの実装
クラスは複数のインターフェースを同時に実装できる。
明解Java入門編 第13章まとめ
抽象クラス
インスタンスを生成できない、またはすべきでない。
メソッドの本体が定義できない。その内容はサブクラスで具体化すべきであるという性質を持ったクラスを表す。
抽象メソッドを一個でも有するクラスは必ず抽象クラスとして宣言しなければならない。
下位クラスをグループ化して多相性を有効活用するためのクラスに具体的な実体がなければ抽象クラスとして定義すると良い。
抽象クラスから派生したサブクラスで抽象メソッドを実装しなければ抽象メソッドのまま継承される。
抽象メソッド
メソッドの前にabstractをつける。
ここではメソッドの実体を定義できないから私から派生したクラスで定義してというニュアンスを持つ。
抽象メソッドには本体がないのでその宣言では{}の代わりにたとえ空であっても;を置く。
スーパークラスの抽象メソッドをオーバーライドしてメソッド本体の定義を宣言することをメソッドを実装するという。
抽象性をもつ非抽象メソッドの設計
スーパークラスの非抽象像メソッドを抽象メソッドとしてオーバーライドできる。
文書化コメント
形式:/**...*/
javadocツールによって、マニュアルともいうべきドキュメントを生成できる。
文書化コメントの対象は、クラス・インターフェース・コンストラクタ・メソッド・フィールドである。
HTMLタグを挿入できる。
明解Java入門編 第12章まとめ
派生と継承
あるクラスをコピーして、部分的な追加・修正を施すプログラミングを続けていくと、互換性のないクラスが溢れかえってしまうため、プログラムの開発効率・拡張性・保守性が低下することになる。そのためソースプログラムの安易な切り貼りによって新しいクラスを作るべきではない。
このような問題を解決するのがクラスの派生である。
派生とは
既存クラスのフィールドやメソッドなどの資産を継承した新しいクラスを作り出すこと。
フィールドやメソッドを追加したり上書きすることもできる。
派生元のクラス(呼び方)
親クラス/上位クラス/基底クラス/スーパークラス
派生したクラス(呼び方)
子クラス/下位クラス/派生クラス/サブクラス
サブクラスはスーパークラスのフィールドやメソッドなどの資産を継承するとともに、それを部分として含むクラスである。
派生とコンストラクタ
クラスの派生においてコンストラクタは継承されない。
コンストラクタの先頭でsuper(...)を実行することによって、スーパークラスのコンストラクタを呼び出せる。
明示的にsuper(...)を呼び出さないコンストラクタの先頭行には、スーパークラスに所属する「引数を受け取らないコンストラクタ」を呼び出すsuper();が挿入される。
コンストラクタを一個も定義しないクラスには、x(){super();}という形式のデフォルトコンストラクタが自動的に定義される。
クラスにコンストラクタを定義しない場合、そのスーパークラスが「引数を受け取らないコンストラクタ」を持っていなければならない。
「super.メンバ名」によって、スーパークラスのメンバをアクセスできる
Objectクラス(親玉クラス)
明示的な派生の宣言をしないクラスはObjectクラスのサブクラスとなる。
javaのすべてのクラスはObjectクラスの下位クラスである。
差分プログラム
継承のメリットの一つに「既存プログラムに対する必要最低限の追加・修正だけで新しいプログラムが完成する」という差分プログラムが行えるということがあげられる。プログラム開発時の効率アップや保守性の向上が図れる。
is-Aの関係
スーパークラス型の変数はサブクラスのインスタンスを参照できるが、サブクラス型の変数はスーパークラスのインスタンスは参照できない。(明示的なキャスト演算子を適用しなければならない)
メソッドのクラス型引数に対しては、そのクラス型のインスタンスへの参照だけでなく、そのクラスの下位クラス型のインスタンスへの参照を渡すことができる。
メソッドのオーバーライド
スーパークラスのメソッドと同形式のメソッドに、サブクラスで別の定義を与えることをオーバーライドすると表現する。
@Overridアナテイション
コメントより高度な注釈で、人間だけでなくコンパイラにも読ませる注釈。
スーパークラスのメソッドをオーバーライドするメソッドには@Overrideアナテイションをつけて宣言すると良い。
メンバ
クラスの派生で継承されるのはクラスのメンバに限られることになっている。
・フィールド
・メソッド
・クラス
・インターフェース
スーパークラスのメンバは原則としてそのまま継承される。
ただし、非公開アクセス性を持つメンバ(private宣言されたメンバ)は継承されない。
メンバではないクラスの資産
・インスタンス初期化子
・静的初期化子
・コンストラクタ
これらの資産は継承されない。
finalなクラスとメソッド
finalクラスのメソッドはすべてfinalメソッドとなる。
finalクラス
final付きで宣言されたクラスやメンバは派生において特別な扱いを受ける。
finalクラスから派生を行うことはできない。拡張すべきでないクラスは(勝手にサブクラスを作られると困る)finalクラスとして宣言すること。
finalメソッド
finalメソッドはサブクラスでオーバーライドすることができない。サブクラスでオーバーライドされるべきではないメソッドはfinalメソッドとして宣言すること。
明解Java入門編 第11章まとめ
パッケージ
主な役割は3つ
1.名前の衝突回避
2.カテゴリによる分類
3.カプセル化(アクセス制御)
同一名のクラスは異なるパッケージに属していれば使い分けられる。
階層化できる。例)Scannerクラスはjavaパッケージの中のutilパッケージに属す。
階層的なパッケージの名前は各パッケージ名を.で区切って表現することになっている。例)java.util
完全限定名
例)java.util.Scanner
単純名
例)Scanner
型インポート宣言
パッケージ名を省略した単純名だけで型を利用可能にする。2種類ある。
単一型インポート宣言
import 完全限定名;
この形式でインポートされた型名はそのソースプログラム内で単純名だけで利用できる。
オンデマンド型インポート宣言
ソースファイル中で利用する全クラスに対して単一型インポート宣言を行うのは大変。そのための簡略的なインポート方法。
import パッケージ名.*;
パッケージ名で指定されたパッケージに所属する型名を、単純名だけで利用できる。
オンデマンドは「必要に応じて」という意味なので使われていない型名はインポートされない。
オンデマンド型インポートするパッケージに同一名のクラスが存在するとそのクラスを単純名で利用しようとしたときエラーが生じるのでオンデマンド型インポート宣言は多用すべきではない。
異なる階層のパッケージ中の型名はインポートできない。
java.langパッケージの自動インポート
java言語に密接に関連したクラスが集められているので、自動的にインポートされることになっている。
静的インポート宣言
・クラス変数(静的フィールド)
・クラスメソッド(静的メソッド)
の2つのインポートを行う。
単一静的インポート宣言
import static 型名.識別子名;
オンデマンド静的インポート宣言
import static 型名.*;
特定のクラスに所属するクラス変数またはクラスメソッドを多用するプログラムでは、オンデマンド静的インポート宣言をするとよい。
パッケージ宣言
package パッケージ名;
・パッケージ宣言はなくてもよい
・パッケージ宣言を2個以上置くことはできない
同一のパッケージ内に所属するクラスは、単純名でアクセスできる。
無名パッケージ
ソースファイルにパッケージ宣言がない場合、そのソースファイル中で定義したクラスは無名パッケージに所属することになっている。無名パッケージに所属するクラスの完全限定名は、単純名と一致する。テスト的な使い捨てのものでない限り、クラスはパッケージに所属させるべきである。
パッケージとクラスの命名での注意
一つのパッケージ中に同一名のパッケージとクラスが存在することは許されない。
パッケージ名はすべて小文字とする。
パッケージとディレクトリ
パッケージを作成する場合は、パッケージ名と同一のディレクトリの中にソースファイルとクラスファイルを置くのが基本的構成である。
一意なパッケージ名
パッケージには一意な名前を与える必要がある。
推奨されているのはインターネットのアドレスを逆順に並べるという方法。識別子として許されていないハイフンなどの特殊文字は下線文字に置き換える。キーワードと一致する単語にはその後ろに下線文字を付加する。先頭文字が識別子の開始文字として許されていない場合はその単語の前に下線文字を付加する。
クラスのアクセス制御
クラスのアクセス性はパッケージという観点から2種類に分けられる。
publicクラス
キーワードpublic付きで宣言されたクラス
パッケージとは無関係に利用できる。
クラスのアクセス性は公開アクセスになる。
publicクラスの名前とソースプログラムのファイルの名は一致していなければならない。
1個のソースプログラムにはpublicなクラスを0個または1個しか定義できない。
非publicクラス
キーワードpublicを付けずに宣言されたクラス
そのクラスが所属するパッケージ内からは利用できるが、他のパッケージからは利用できない。
クラスのアクセス性はパッケージアクセスとなる。(デフォルトアクセスとも呼ばれる)
メンバのアクセス制御
あるクラスに所属するクラス変数・インスタンス変数・メソッドなどをまとめてクラスのメンバと呼ぶ。
メンバのアクセス性には4種類ある。
公開(public)アクセス
パッケージの中からも外からも利用できる
限定公開アクセス
パッケージの中からのみ利用できる
パッケージアクセスと違い、パッケージの内部からだけでなく、そのクラスから派生した異なるパッケージに属するサブクラスからも利用できる
パッケージアクセス
同じパッケージの中からのみ利用できる
非公開(private)アクセス
クラスの内部でのみ利用できる
同じパッケージに所属するクラスからは利用できない
明解Java入門編 第10章まとめ
クラス変数
staticを付けて宣言されたフィールドはクラス変数(静的フィールド)となる。
個々のインスタンスではなくクラスに所属する。そのため、クラス変数のアクセス式は『クラス名.フィールド名』となっている。
または『クラス型変数名.フィールド名』という式でもアクセスできるが紛らわしい書式なのでオススメではない。
ソースファイルとpublicクラス
一つのソースプログラム内で、二つ以上のpublicクラスを宣言することはできない。
publicかつfinalなクラス変数の公開
クラス利用者に提供すべき定数があれば、publicかつfinalなクラス変数として提供すると良い。
クラスメソッド
特定のインスタンスではなくクラス全体に関わる処理や、そのクラスに所属する個々のインスタンスの状態とは無関係な処理は、静的メソッドとして実現する。
異なるシグネチャで同一名のメソッドを定義する多重定義は、クラスメソッドとインスタンスメソッドにまたがって行える。
クラスメソッドの呼び出し
クラス名.メソッド名(...)
インスタンスメソッドの呼び出し
クラス型変数名.メソッド名(...)
非静的メソッド(インスタンスメソッド)
非静的フィールド・静的フィールド・非静的メソッド・静的メソッドのすべてをアクセスできる。自分が所有する変数/メソッドと、みんなで共有する変数/メソッドの両方にアクセスできる。
静的メソッド(クラスメソッド)
静的フィールドと静的メソッドにはアクセスできるが、非静的フィールドと非静的メソッドにはアクセスできない。自分が所有する変数/メソッドをもたないクラスメソッドは、みんなで共有する変数/メソッドにしかアクセスできない。
ユーティリティクラス
内部にステート=状態をもたないので、データとそれを処理するための手続きをカプセル化するというクラス本来の目的をもたない。類似した機能のメソッドや定数を集めてグループ化したもの。
クラス初期化(静的初期化子)
静的ブロックあるいはstaticブロックなどとも呼ばれる。
クラスが初期化される際実行される。
クラスが初期化されるタイミング
・そのクラスのインスタンスが生成される
・そのクラスのクラスメソッドが呼び出される
・そのクラスのクラス変数に値が代入される
・そのクラスの定数ではないクラス変数の値が取り出される
なんらかの形でクラスを初めて利用する時点ではそのクラスのクラス初期化子の実行が完了している。
クラス変数を初期化するために必要な処理は、クラス初期化子で行うと良い。
インスタンス初期化子
クラス内の全コンストラクタで共通に行うべき処理(インスタンス生成のたびに必ず行うべき処理)があればインスタンス初期化子として独立させるとよい。
明解Java入門編 第9章まとめ
ゲッタとセッタとアクセッサー
getter:フィールドの値を取得するメソッド
setter:フィールドに値を設定するメソッド
accessor:両者の総称
クラス型変数の代入
クラス型の変数を同一型の変数によって初期化するか、同一型の変数を代入すると、参照先がコピーされる。全フィールドの値がコピーされるわけではない。
クラス型変数の比較
クラス型変数に適用された等価演算子==と!=は、参照先が同一であるかないかを判定する。フィールドの値が等しいかどうかの判定を行うわけではない。
クラス型インスタンスの配列
クラス型のインスタンスの配列を利用するためには、クラス型変数の配列を生成した後に、個々の要素のインスタンスを生成しなければならない。
publicクラス
publicの有無によってクラスのアクセス性が変わる。
public無し:そのクラスは同一パッケージの中でのみ利用できるものとなる
public有り:そのクラスはどこからでも利用できるものとなる。
小規模で使い捨てのクラスでない限りクラスには原則としてpublicを付けて宣言する。
publicクラスの中でpublic付きで宣言されたメソッドは、パッケージとは無関係にどこからでも利用できるものとなる。
コンストラクタ多重定義
メソッド同様コンストラクタは多重定義できる。必要であればコンストラクタを多重定義しクラスインスタンス構築のための複数の方法を提供せよ。
コピーコンストラクタ
自分自身と同じクラス型の引数を受け取って全フィールドの値をコピーするコンストラクタのこと。
toString:文字列を返すメソッド
そのクラスのインスタンスの現在の状態を文字列表現で返却するメソッドは以下の形式で定義する。
public String toString() { /*...*/ }
文字列の連結について
「文字列+クラス型変数」あるいは「クラス型変数+文字列」の演算では、そのクラス型に対してtoStringメソッドが自動的に呼び出されて文字列に変換された上で文字列の連結が行われる。
フィールドの初期化
フィールドの宣言に初期化子を与えておけば、そのフィールドはインスタンス生成時に与えられた初期化子の値で初期化される。
同一クラス内のコンストラクタの呼び出し
コンストラクタの先頭ではクラス内の他のコンストラクタを、this(...)によって呼び出すことができる。
同一あるいは類似のコードをクラス中に散在させるべきではない。行う処理が他のメソッドやコンストラクタで実現されていればそのメソッドやコンストラクタを呼び出すべきである。
参照を返すメソッド
参照値を通じて外部から間接的に値を書き換えられてしまうので、不用意に参照型フィールドの値を返却してはいけない。
コンポジション
has-Aの関係
あるクラスがその一部分として別のクラスをもつこと