• ベストアンサー

メソッドのオーバーロードとオーバーライドのシグニチャはどうして違うの?

オーバーロードのほうはメソッド名+引数の数+引数のデータ型ですが、オーバーライドのほうはそれに加えて戻り値の型も加わります。 どうして同じではいけないのでしょうか?

  • Java
  • 回答数4
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • UKY
  • ベストアンサー率50% (604/1207)
回答No.4

まず、シグネチャという言葉の使い方が間違っています。Javaにおいて「メソッドのシグネチャ」とは「メソッドの名前と引数の数と引数の型」という意味です。したがって「オーバーライドのシグネチャ」とか「オーバーロードのシグネチャ」などという表現は意味を成しません。「オーバーライド時に共通させるもの」などと表現してください。 > 一応どのクラスが何をするのかということを把握して作成しているものには何も不都合が感じないと思いますが。ここでは大規模開発のことで他人の作成した…… その程度ではオブジェクトの「多態性」は実現できません。 サブクラスがスーパークラスと互換性のあるインターフェースを備えていることのは多態性の必要条件です。そうでなければサブクラスにスーパークラスの振りをさせる意味がありません。(スーパークラスとサブクラスという親子関係を作る意味がないといっても良い) 二つのクラスに親子関係を作り、両者に互換性(というか共通性)を持たせようとするのであれば、オーバーライド関係にあるメソッドの振る舞い(=何という名前で何型の引数を受け取り何型の値を返すのか)が同じになるのは当然ではありませんか? Javaは型の扱いが厳密であることも忘れないでください。JavaScriptのような、型を演算時にしかチェックしない放任主義の言語ではないのです。

参考URL:
http://msugai.fc2web.com/java/polymorphism.html
yukikundesuyo
質問者

お礼

サブクラスとスーパークラスの互換性をもたせるためにオーバライドでは戻り値の型まで同じではないといけないということですか。とりあえず分かりました。ありがとうございます。

その他の回答 (3)

回答No.3

オーバーライドは インタフェースはそのままで、振舞いを差し替えるものだからです。

noname#86752
noname#86752
回答No.2

Javaは型が静的なので、もし戻り値の型が変わったら大変だと思いませんか? たとえばクラスPで宣言していたメソッドと、それを継承したクラスCでオーバーライドしたメソッドの戻り値が違った場合、二つのクラスのオブジェクトを実行時に同等に扱うことができません。 実行時に同等に扱えないということは、プログラミングの時点でどのクラスのオブジェクトかチェックしてからメソッドを呼ぶことになり、そうすると「継承しても同じメソッドを同じように呼べる」というオーバーライドのメリット(というより継承のメリット)を殺すことになります。 という理由ではダメでしょうか。 オーバーロードは「同じ名前の別メソッド」だから、あらかじめどのメソッドを呼ぶかをプログラミングの時点で分かっているはずで、当然も戻り値が違うことも分かっています。だから戻り値が変わっても問題ないですね。 型を静的に決定しない言語の場合は戻り値の型というのも存在しないので、ご質問にある制約は全く考える必要がないでしょう。(Rubyとかそうかもしれません)

yukikundesuyo
質問者

補足

>実行時に同等に扱えないということは、プログラミングの時点でどのクラスのオブジェクトかチェックしてからメソッドを呼ぶことになり、 とありますが、一応どのクラスが何をするのかということを把握して作成しているものには何も不都合が感じないと思いますが。というか、ここでは大規模開発のことで他人の作成したプログラムを一々中身を隅から隅まで見ないので、戻り値の型を気にせず、メソッド名だけで判断できるということのための利点でオーバライドでは戻り値の型をシグニチャに含むということなんでしょうか?

回答No.1

質問の意味がよくわかりませんが、こちらを読んでみてください。 http://www2s.biglobe.ne.jp/~yuuki_ki/java_class8.htm

関連するQ&A

  • オーバーライドについて

    はじめまして。 変な質問ですみませんが質問させてください。 オーバーライドの定義についてなのですが、 オーバーライドとは、スーパークラスで定義した、メソッドの メソッド名と戻り値のデータ型と引数の数とそのデータ型が等しい メソッドをサブクラスで定義することであると、 認識しているのですが、間違いでしょうか、 特に、戻り値のデータ型はスーパークラスとサブクラスとで同じでなけ ればならないんですよね? ご教授お願いします。

    • ベストアンサー
    • Java
  • 問題の解説お願いします。(オーバーロード&オーバーライド)

    class A{ protected int method1(int a , int b){ return 0; } } クラスAを継承したクラスで同時に定義できるメソッド が、 public int method1(int a,int b){return 0;} が良くて private int method1(int a,int b){return 0;} static protected int method1(int a,int b){return 0;} がだめな理由がいまいちわかりません。 法則みたいなものにこう書いてありました。 (オーバーロードについて) 同一クラス内に同一名称のメソッドを定義することができます。 ただし、それらは引数が異なるものでなければならず、 アクセス制御修飾子や戻り値の型だけが異なるメソッドは 定義することができません。 (オーバーライドについて) サブクラスでは、スーパークラスに存在するメソッドと同一引数・ 同一戻り値型を持つメソッドを定義することが許されています。 これら以外にも何か決まりがあるのでしょうか よろしくお願いします。

    • ベストアンサー
    • Java
  • オーバーライドとオーバーロードについて

    1.CTestDlgクラスを作成 class CTestDlg : public CDialog { // コンストラクション public: BOOL Create(CWnd *pWnd); CWnd * m_pParent; CTestDlg(CWnd* pParent = NULL); // 標準のコンストラクタ・ ・ 2.メンバ関数の定義 BOOL CTestDlg::Create(CWnd *pWnd) { m_pParent = pWnd; BOOL bret = CDialog::Create( CTestDlg::IDD, m_pParent); if( bret == TRUE) { this->ShowWindow( SW_SHOW); } return bret; 以上のような場合において、 1.Create(CWnd *pWnd)は、引数が異なるため virtual BOOL Create( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL ); をオーバーライドしたとは言わず、オーバーロードしたということで良いのでしょうか? 2.オーバーロードしたということであれば、 Create(CWnd *pWnd)と virtual BOOL Create( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL ); の両方の関数が使えると思っていたのですが、後者方は引数が異なるとエラーが出て使えませんでした。 どうしてなのでしょうか? 以上、2点についてご教授ください。

  • 匿名クラス内のメソッドをオーバーライド。実引数はいつどこから来るのでしょうか?

     お世話になっております。 匿名クラス内のメソッドをオーバーライドするときの引数についての質問なのですが File d = new File("F:\\dir"); File[] d2 = d.listFiles(new FileFilter(){ public boolean accept(File hoge){ return hoge.toString().endsWith(".txt"); } } ); オーバーライドしたacceptメソッドの仮引数のFile型のhogeがありますが このacceptメソッドの実引数はいつどこから来るのでしょうか? このacceptメソッドの実引数はどこで「acceptメソッドの呼び出し」で指定すればよいでしょうか? その他ActionEvent e などの仮引数も謎です。 どうかよろしくご指導お願いいたします。

    • ベストアンサー
    • Java
  • クラスやメソッドが理解できません

    今javaを勉強中なのですが、クラスやメソッドで生きず待ってしまいました。 メソッドの定義は 戻り値の型 メソッド名(引数リスト) {  文;  ・・・ return 式;  } ですが、メソッドから返されえる値を戻り値といますよね?呼び出し元に値を返すってどういうことなのでしょうか? int getNum() { System.out.println("調べました") return num; } たとえば、上記のようなものですが。もしも、このメソッドを呼び出すと、”戻り値”が戻ってくるわけですが、これはgetNumという変数のなかに計算式が入っている?という考え方でいいのでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • Java
  • オーバーロードの「あいまい」エラーについて

    お世話になっております。 メソッドのオーバーロードにおいて、以下の様な場合にコンパイルエラーが発生します。 環境:JDK1.6.0_13 + eclipse3.3.2 public class Sample { static void meth(long... longs){ System.out.println("long..."); } static void meth(Integer... Integers) { System.out.println("Integer..."); } public static void main(String[] args){ meth(100); } } エラーメッセージ:メソッド meth(long[]) は型 Sample であいまいです (以下、「あいまいエラー」と表記します) 今回のケースでは、なぜこの様なエラーが出てしまうのか、今一つわからずに困っています。 「あいまいエラー」について少し調べを入れてみましたが、 参照型を引数に取るメソッドが複数ある時にnullを渡した時など、 明瞭にわかりやすいケースの例示は見つかったのですが、 今回の様なケースに当てはめて納得の行く情報ソースは見つけられませんでした。 まとめますと、私の欲しい情報は、 可変長引数リストを引数に取るオーバーロードメソッドが複数ある時に、 「あいまいエラー」が発生する規則です。 以上です。よろしくお願いします。

    • ベストアンサー
    • Java
  • メソッド宣言の戻り値の型にクラス名を使うには?

    メソッドの戻り値の型にクラス名を使ってるプログラムを見かけたのですが、例えばクラス名を public class Player{ とします。そして Playerクラスのメソッド宣言に  private   Player(戻り値の型) startRun(メソッド名) { とあります。 これは戻り値の型にクラス型の変数を使ってユーザー定義してると思うのですが使い方が分かりません。 javaのサイトはできるだけ調べたのですが戻り値の型にクラス名を使うにはどうすればいいか分かりませんでした。 この使い方を教えてくれるサイトを教えてください。 基本型と参照型のStringクラスについて教えてくれるサイトはたくさん見かけたのですが…。 お願いします。

    • ベストアンサー
    • Java
  • Javaのオーバーライドについて教えてください!

    //Sample.java class A extends Fina{ public int part(String str1,String str2){ int iN1 = Integer.parseInt(s1); int iN2 = Integer.parseInt(s2); intNum1 *= intNum2; return intNum1; } } このプログラムに対応するように同じクラス内でオーバーロードした際のプログラムを教えてください。 オーバーロードの内容は、partメソッドをオーバロードして引数にString型のデータを二つ受け取り、2つのString型のデータをそれぞれint型に変換し、それぞれかけた値を別のクラスでメインから呼び出すにはどうすれば良いですか?

    • ベストアンサー
    • Java
  • c# メソッド名について

    こんにちは。c#初心者です。  現在メソッドの命名について尋ねたいことがあります。  戻り値をもつタイプのメソッド「SampleMethod」があったのですが、そこにほぼ同じ動作で戻り値を持たない代わりに「out」キーワードで値を取得させるメソッドを追加しました。  そこで命名しなければならないのですが、「SampleMethod2」のような語尾に数字をつけるような命名は好ましくないのでしょうか?  しっかりと区別したいのでオーバーロードするつもりはありませんが、インテリセンスで互いにすぐ近くに出てくれたほうが何かと助かります。  初心者なので細かい命名規定などは分かりませんのでどなたか詳しい方、分かる方がいらっしゃればご意見を伺わせてもらえませんか?

  • オーバーライドの必要性

    まだまだJavaを勉強している途中なのですが、下記のサンプルコードでオーバーライド(メソッドをオーバーロードすることをオーバーライドというのでしょうか…!?)のの必要性がよく分からなくなってしまったので質問させて頂きました。 /* sample.java */ abstract class super_class{  void write(){} } class CLASS1 extends super_class{  void write(){ System.out.println("CLASS1"); } } class CLASS2 extends super_class{  void write(){ System.out.println("CLASS2"); } } class sample{  public static void main(String args[]){   super_class obj = new CLASS2();   obj.write();   obj = new CLASS1();   obj.write();  } } 以上のコードを実行した場合 CLASS2 CLASS1 と表示されるのは多少なりとも勉強して分かったつもりでした…。 しかし、あくまでサンプルであるために特に意味がないことでもオーバーライドの説明をしているのだろうという風に考えてしまったのですが、 結局は、 スーパークラスとサブクラスに同じシグネチャのメソッドがあった場合、各サブクラスのメソッドが実行される と言うことは、スーパークラスのwrite()メソッドは何をしているのでしょうか? 多様性はJavaでも大切なものであるとのことなので質問させて頂きました。 なるべくわかりやすく説明して頂きたいと思います。 どうかお答えをお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう