主旨
- JavaGold資格取得に向けて学習したことの内容メモ(黒本をまずは読んでみる)
- 記憶の怪しい項目や知らなかったことをまとめる
- あとで見返せる程度で備忘録を残す(多分意味が自分しか理解できない記載も多い)
- 完全なメモなので誤字などもあるかもしれないが細かいことはひとまず気にしないでおく
Javaのクラス設計について
■カプセル化
・外部に公開するアクセス手段のメソッド→アクセサメソッド o r アクセサ
・finalやstaticを実装することとカプセル化は無関係
・トップレベルクラス→ネストされたクラスでない通常のクラス→ファイル名がFoo.javaでクラスがFooの場合、トップレベルクラス
・一つのソースにおいて、宣言できるpublicなトップレベルクラスは一つだけ
■継承
・is-a関係(AはBである) or kind -of-a関係(AはBの一種である)
・has-a関係(AはBを持っている)は、集約の関係。構成集約とも呼ばれる。
・集約は関係するオブジェクトのライフライクルが同じではない→親クラスと学生クラス。親クラスを削除しても子クラスは残る。
・構成集約は関係するオブジェクトのライフサイクルが同じ。Is-a-part-of関係とも呼ぶ→家クラスと部屋クラス。部屋クラスは家クラスがなくなると存在できない。依存関係
・is-a→継承
・has-a(Aggregation:白の◇)は集約
・has-a(Composition:黒の🔷)は依存
■ポリモーフィズム
・コンパイル時に決定する静的な型
・実行時に複数の型を扱うことができる仕組み
・継承関係で持ちいることが多い(is-a関係)
・インターフェイスの実装、クラスやインターフェイスの継承
・インターフェイスで宣言されている抽象メソッドを実装する場合にも@Overrideアノテーションを記述できるが、正しく実装できていない場合はアノテーションの有無に関わらずコンパイルエラーになる。
■java.lang.Objectクラス
・equals(Object obj)、int hashCode()、String toString()メソッドが主要なメソッド。
■System.out.printlnメソッド
・toStringメソッドをオーバーライドしていない場合→[完全修飾クラス@ハッシュ値の16進数の文字列
・[は配列、L完全修飾クラス名は要素の型を表す
・全てのクラスにおいてtoStringメソッドを適切にオーバーライドすることが推奨
・戻り値として文字列にフィールドの値を含むなど
■equalsメソッド
・全てのオブジェクトのequalsメソッドの比較はメモリアドレスの比較
・StringやIntegerはequalsメソッドをオーバーライドしており、フィールドの値の比較を行う
・StringやIntegerクラスは同じ値を保持しておれば、インスタンスの実態が異なっても同じと扱う
・null以外の参照値xにおいて、x.equals(nulll)はfalseを返却
■hashCodeメソッド
・呼ばれたインスタンスのハッシュ値を返却する→メモリアドレスを基にした値
・ハッシュ値の代表的なものとしてMD5やSHAがある→不可逆性、一方向性→理論上は元データを復元できない
・オブジェクトを検索する時にパフォーマンスを向上させる
・equalsメソッドによって等しいオブジェクトは必ず同じ値になる
・equalsメソッドによって等しくないオブジェクトは必ず同じ値を返さないといけないわけではない
・異なるオブジェクトは異なるハッシュ値を返すことが理想→通常検索で用いるので
■final
・クラス→継承不可→abstractは不可、コンパイルエラー
・フィールド→再代入不可
・メソッド→オーバーライド不可→abstractは不可、コンパイルエラー
・メソッドの引数、ローカル変数で使用することは可→引数でうけとった値を変更する必要がないときには推奨
■クラスとインスタンス
・クラスは静的→コンパイル時に決定
・インスタンスは動的→プログラム実行中にnewされヒープ領域(メモリ)に生成される
・staticフィールドはfinalをつけることが推奨
・クラス名.staticフィールド名、クラス名.staticメソッド名で使用する
・staticメンバーはクラス名による参照が推奨、
■static変数をコード・ブロックで初期化
・static初期化子を用いる
static {
// 初期化コード
}
・クラスがロードされたタイミングで使用
■シングルトンを実装するには
・自身をフィールドとして保持。private staticフィールド
・コンストラクタをprivate
・自身のインスタンスを返却するpublic staticメソッド
pubilc class A {
private static final A a = new A();
private A() {}
public static A getInstance() { return a;}
}
■不変クラス
・Immutable Classという
・生成されたインスタンスのフィールド値を変更できないように設計されたクラス
・java.lang.Stringクラスなど
・クラスはfinal
・フィールドはprivate final
・メソッドはgetterのみ
■インターフェイス
・抽象メソッドの他にdefaultメソッドとstaticメソッドの宣言が可
・defaultメソッド→インターフェイス名.メソッドで呼び出す。実装クラスを用いて呼び出せない(コンパイルエラー)、実装クラスにおいて最初から実行が可能
・関数型インターフェイスは抽象メソッドを1つだけ保持できる
・同じシグニチャ(メソッド名、引数などが同じ)のdefalutメソッドを持つインターフェイスを複数実装した場合にはコンパイルエラー→防ぐにはオーバーライド
・defaultメソッドが型階層(インターフェイスを継承して、実装するなど)においては先にオーバーライドされた内容が適応される
■抽象クラス
・インスタンス生成不可
・具象メソッドと抽象メソッドの両方の宣言が可
・実装を記述することはできない
・抽象クラスを継承する場合はメソッドをオーバーライド or 自身も抽象クラスにする
・実装しないメソッドを継承する場合抽象クラスにしないとコンパイルエラー
■入れ子クラス
・メンバークラス、staticメンバークラス、ローカルクラス
・static以外のクラスを内部クラスといい、匿名クラス(関数の引数として使う場合に、その場で宣言して利用する)として利用できる
■内部クラス
・(例) Outer.Inner inner = new Outer().new Inner();→外側のクラス.内部クラス 変数名;→他のクラスから呼ぶ場合
・同じクラスのメソッド内では通常通り呼べる
・staticは内部クラスはそのまま呼べない→まずは自身のクラスをnewしてから呼ぶ必要あり
■匿名クラス
・インターフェイスの実装をその場で行うときなどに用いる
・new クラス名() {
//抽象メソッドの実装
}
■列挙型(Enum)
・修飾子 enum 識別子 {列挙定数1, 列挙定数2, ...}
・トップレベル、入れ子クラスの中で使える→メソッド内は不可
・列挙型はクラスなのでフィールドやメソッドをメンバーに保持できる
・列挙定数には修飾子をつけることはできない。
・他のクラスを継承できない
・インターフェイスの実装は可能
・列挙型はfinalクラスに暗黙的にコンパイルされるので、final, abstractは使用不可
・トップレベルではpubilcもしくはデフォルトのみ修飾子として可→ネストされている場合はstatic扱い
・列挙定数名を取得するnameメソッドがある→final扱い
・toStringメソッドのオーバーライドの実装も提供している→推奨(カスタマイズした文字列を返却できるから)
・文字列から列挙型インスタンスを取得するにはvalueOfメソッドを使用→存在しない場合はIllegalArgumentExceptionがスローされる
・ordinal()メソッド→列挙定数の宣言された順番の数値を返す→0から開始
・values()メソッドは列挙型の配列を返却
・コンストラクタはprivateのみ
ふりかえり
- 列挙型や内部クラスはこれまで扱ってきてなかったので、意味や書き方のルールなどをもっと学習する必要があると感じた。