重複の可能性:
ポリモーフィズム vs オーバーライド vs オーバーロード
Javaで メソッドのオーバーロードとオーバーライドが必要な理由を知るのに苦労していますか?
これに関するいくつかの記事を読みましたが、実際に必要な理由を理解できませんか?
また、stackoverflow で以下の URL にアクセスしましたが、このトピックについてはまだ明確ではありません。
実用的な例をいただければ幸いです。
前もって感謝します。
重複の可能性:
ポリモーフィズム vs オーバーライド vs オーバーロード
Javaで メソッドのオーバーロードとオーバーライドが必要な理由を知るのに苦労していますか?
これに関するいくつかの記事を読みましたが、実際に必要な理由を理解できませんか?
また、stackoverflow で以下の URL にアクセスしましたが、このトピックについてはまだ明確ではありません。
実用的な例をいただければ幸いです。
前もって感謝します。
ドキュメントから
メソッドのオーバーロード:カリグラフィーを使用してさまざまなタイプのデータ (文字列、整数など) を描画でき、各データ タイプを描画するためのメソッドを含むクラスがあるとします。メソッドごとに新しい名前 (たとえば、drawString、drawInteger、drawFloat など) を使用するのは面倒です。Java プログラミング言語では、すべての描画メソッドに同じ名前を使用できますが、各メソッドに異なる引数リストを渡すことができます。したがって、データ描画クラスは draw という名前の 4 つのメソッドを宣言し、それぞれに異なるパラメーター リストがあります。
public class DataArtist {
...
public void draw(String s) {
...
}
public void draw(int i) {
...
}
public void draw(double f) {
...
}
public void draw(int i, double f) {
...
}
}
オーバーロードされたメソッドは、メソッドに渡される引数の数と型によって区別されます。コード サンプルでは、draw(String s)
とdraw(int i)
は異なる引数の型を必要とするため、明確でユニークなメソッドです。
コンパイラはそれらを区別できないため、同じ名前、同じ数と型の引数を持つ複数のメソッドを宣言することはできません。
コンパイラは、メソッドを区別するときに戻り値の型を考慮しないため、戻り値の型が異なっていても、同じシグネチャで 2 つのメソッドを宣言することはできません。
メソッドのオーバーライドは、オブジェクト指向プログラミングで、サブクラスまたは子クラスが、そのスーパークラスまたは親クラスの 1 つによって既に提供されているメソッドの特定の実装を提供できるようにする言語機能です。サブクラスの実装は、親クラスのメソッドと同じ名前、同じパラメーターまたはシグネチャ、同じ戻り値の型を持つメソッドを提供することで、スーパークラスの実装をオーバーライド (置換) します。実行されるメソッドのバージョンは、それを呼び出すために使用されるオブジェクトによって決まります。親クラスのオブジェクトを使用してメソッドを呼び出すと、親クラスのバージョンが実行されますが、サブクラスのオブジェクトを使用してメソッドを呼び出すと、子クラスのバージョンが実行されます。
オーバーライド
Java ドキュメントは次のように述べています。
スーパークラスのインスタンス メソッドと同じシグネチャ (名前とそのパラメータの数と型) と戻り値の型を持つサブクラスのインスタンス メソッドは、スーパークラスのメソッドをオーバーライドします。
メソッドをオーバーライドするサブクラスの機能により、クラスは、動作が「十分に近い」スーパークラスから継承し、必要に応じて動作を変更できます。
オーバーライドは、継承の使用中に使用できる機能です。
別のクラスから拡張されたクラスが親クラスのほとんどの機能を使用したい場合や、特定のケースで特定の機能を実装したい場合に使用されます。
このような場合、親クラスと同じ名前とシグネチャを持つメソッドを作成できます。このようにして、新しいメソッドは親メソッドをマスクし、デフォルトで呼び出されます。
class Thought {
public void message() {
System.out.println("I feel like I am diagonally parked in a parallel universe.");
}
}
public class Advice extends Thought {
@Override // @Override annotation in Java 5 is optional but helpful.
public void message() {
System.out.println("Warning: Dates in calendar are closer than they appear.");
}
}
Java でのオーバーロードとは、同じ名前でパラメーターが異なる複数のメソッドを作成する機能です。
これの主な利点は、コードのクリーンさです。
方法を取りましょうString.valueOf
。このメソッドのオーバーロードされたバージョンは、次のように定義されています。
static String valueOf(boolean b)
static String valueOf(char c)
static String valueOf(char[] data)
static String valueOf(char[] data, int offset, int count)
static String valueOf(double d)
static String valueOf(float f)
static String valueOf(int i)
static String valueOf(long l)
static String valueOf(Object obj)
これは、任意のタイプの変数がある場合、 を使用してその文字列表現を取得できることを意味しString.valueOf(variable)
ます。
オーバーロードが許可されていない場合、次のようなメソッドがあります...
static String valueOfBoolean(boolean b)
static String valueOfChar(char c)
static String valueOfCharArray(char[] data)
static String valueOfCharArrayWithOffset(char[] data, int offset, int count)
static String valueOfDouble(double d)
static String valueOfFloat(float f)
static String valueOfInt(int i)
static String valueOfLong(long l)
static String valueOfObject(Object obj)
...これは、オーバーロードされたソリューションよりも非常に見苦しく、読みにくいものです。
答えは、主にinterface
s とabstract class
es の使用に集中しています。
コードのブロックがあるとしましょう:
abstract class testAbstract {
int a; int b; int c;
public String testFunction() {
System.out.println("Override me!");
return "default";
}
public void setValuesByFormula(double a, double b) {
System.out.println("No formula set!");
}
}
これは賭けの例ではありませんが、ユーザーが数式からa
、b
、を設定できるようにすることを意図しているとしましょう。c
ユーザーは、これの新しいインスタンスを作成したいと考えています:
class testClass extends testAbstract {
}
クラスtestClass
には現在... 何も含まれていません。しかし、それは拡張testAbstract
されているため、機能を持っていますsetValuesByFormula
。ただし、ユーザーがこれを呼び出そうとすると、システムは次のメッセージを出力します。No formula set!
この時点でユーザーが行う必要があるのは@Override
、本来の機能です。したがって、新しいクラスは次のようになります。
class testClass extends testInterface {
public void setValuesByFormula(double a, double b) {
//A not really relevant formula goes here.
}
}
No formula set!
これにより、ユーザーが独自の式を作成したため、メッセージが停止します。これが必要になる主な理由は次のとおりです。