Java の学習ノートを記録しておきます。
重载#
重载:重载は、メソッドのオーバーロードを指します。オーバーロードの特徴は、2 つ以上のメソッドが同じ名前を持つことです。
クラシックなオーバーロードメソッド#
オーバーロードは主にコンストラクタメソッドで使用されます。なぜなら、コンストラクタの役割はオブジェクトの構築を初期化することであり、コンストラクタの名前はクラス名と同じでなければならないため、これがクラシックな引数なしコンストラクタと引数付きコンストラクタのペアとなります。
以下に例を示します:
なぜオーバーロードが必要なのか#
私たちは皆、Java で最も重要な概念である「オブジェクト」を知っています。そのため、メソッドはオブジェクトの個々の動作です。同じ名前のメソッドでも、実際には異なることをしている場合があります。例えば、小明が麻雀を打っているとします。
文字通りの意味:小明は他の人と一緒に麻雀をするというエンターテイメント活動
他の意味:小明は「麻雀」という名前の人を「打つ」
したがって、現実の生活の言語の曖昧さはコードでも起こり得ます。
また、ある人が何かを食べている場合、私が彼に何かを与えると、彼はそれを食べます。私が彼に麺を与えると、彼の行動は「麺を食べる」です。私が彼にご飯を与えると、彼はご飯を食べますが、彼の行動はすべて「食べる」と呼ばれます。
要約すると、オーバーロードはコードで非常に必要です。
オーバーロードの区別#
同じ名前の異なるメソッドをどのように区別しますか?
オーバーロードを区別するための重要な原則:各オーバーロードメソッドには一意のパラメータタイプリストが必要です(つまり、各メソッドには他の同名のメソッドとは異なる引数があります)
では、どのようなパラメータリストが異なるのでしょうか?
パラメータタイプの違い#
出力結果:
パラメータの順序の違い#
パラメータの順序が異なる場合、同じ名前のオーバーロードメソッドを区別することはできますが、この方法は推奨されません。なぜなら、このようにコードを書くと、メンテナンスが困難になるからです。
出力結果:
戻り値によるオーバーロードメソッドの区別#
パラメータリストの型、順序だけでなく、戻り値を使用してオーバーロードメソッドを区別することはできますか?
答えはできません、以下に例を示します。
f()
メソッドを呼び出す必要がありますが、戻り値は必要ありません(System.out.println
メソッドなど)。この場合、Java はどのメソッドを呼び出す必要があるかを区別することはできません。
基本型のオーバーロード#
基本型のみが異なるオーバーロードメソッドの場合、基本型は小さい型から大きい型に自動的に昇格する場合があります。
出力結果:
変数 x は int 型ですが、checkBasicTypes()
メソッドには int 型の引数がありません。プログラムが実行されると、int 型よりも大きい型のメソッドを呼び出すため、渡されるデータ型が自動的に昇格されます。( int -> long)
重写#
重写は通常、親子クラスの関係で発生し、親クラスと子クラスの間には 2 つの名前とパラメータリストが同じメソッドがあります。同じメソッド名を持つため、メソッド呼び出し時には子クラスのメソッドが親クラスの同名メソッドを上書きします。
以下はオーバーライドの例です。
出力結果:
上記の例では、親クラスと子クラスの両方で say()
メソッドが定義されていますが、実際には子クラスが親クラスの say()
メソッドをオーバーライドしています。
オーバーライドされたメソッドでは、子クラスのオブジェクトの say()
メソッドを呼び出すと、Dog オブジェクトの型が Animal であっても、Java は Dog の say()
メソッドを呼び出します。つまり、子クラスのメソッドは同名の親クラスのメソッドを上書きします。
重写の原則#
メソッドをオーバーライドする場合、リスコフの置換原則を満たす必要があります:
- サブクラスのメソッドのアクセス権限は、スーパークラスのメソッドのアクセス権限以上でなければなりません。
- 例:スーパークラスのメソッドの修飾子が protected の場合、サブクラスのメソッドの修飾子は protected または public でなければなりません。
- サブクラスのメソッドの戻り値の型は、スーパークラスのメソッドの戻り値の型と同じか、そのサブタイプでなければなりません。
- 例:B extends A の場合、スーパーメソッドの戻り値の型が A の場合、サブクラスのメソッドは A 型または B 型を返すことができます。
- サブクラスのメソッドがスローする例外の型は、スーパークラスの例外の型と同じか、そのサブタイプでなければなりません。
@Override アノテーション#
@Override
アノテーションは Java のキーワードではありませんが、キーワードと同じように使用できます。このアノテーションをオーバーライドメソッドに追加すると、コンパイラが上記の 3 つの制限条件をチェックし、オーバーライドメソッドが有効かどうかを確認してくれます。時には、意図しないオーバーロードを防ぐのにも役立ちます。