banner
lMingyul

lMingyul

记录穿过自己的万物
jike
twitter
github
bilibili

重载(overloading)和重写(overriding)是面向对象编程中的两个重要概念。 重载是指在同一个类中,可以定义多个同名的方法,但这些方法的参数类型或参数个数必须不同。通过重载,可以根据不同的参数类型或参数个数来调用不同的方法。 重写是指子类重新定义了父类中已有的方法。子类可以通过重写来修改父类方法的实现,使其适应子类的特定需求。在重写时,子类方法的名称、返回类型和参数列表必须与父类方法保持一致。 重载和重写是面向对象编程中的两种不同的机制,它们都可以提高代码的灵活性和可复用性。在使用时,需要根据具体的需求和场景来选择合适的机制。

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 つの制限条件をチェックし、オーバーライドメソッドが有効かどうかを確認してくれます。時には、意図しないオーバーロードを防ぐのにも役立ちます。

参考資料#

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。