インターフェースと継承のどちらを使ってポリモーフィズムを実現するべきか

ホーム フォーラム Java インターフェースと継承のどちらを使ってポリモーフィズムを実現するべきか

  • このトピックには2件の返信、2人の参加者があり、最後にt-isechiにより7年、 8ヶ月前に更新されました。
3件の投稿を表示中 - 1 - 3件目 (全3件中)
  • 投稿者
    投稿
  • #47
    Atsushi
    キーマスター

    インターフェースの利点がここに来てぼやっとしてきた。
    Webシステムの最終課題はおもいっきり継承を使っていて(Actionクラス)
    ものすごくStrutsライクなつくりになっている。

    Springはインターフェースでゴリゴリやるけれど、Strutsは継承をして
    プロパティーファイルで読み込んできているイメージ。

    インターフェース、継承どちらを利用して設計していくのが正解なのか
    を議論してみたいでござんす。

    #49
    Atsushi
    キーマスター

    インターフェースも継承も、どちらでもポリモーフィズムは実現可能。
    ただ、じゃあインターフェースの存在価値はなに?って部分を考えてみる。

    • 特定の機能が用意されている事を保証するためにインターフェイスが使われる
    • 設計精度、開発効率、保守効率などをアップするために必要なもの
    • 必要な機能だけを定義する際に有効

    クラスを継承した場合は、その継承元のクラスにどのメソッドがあるか等を把握しておかない限り、
    オーバーライドや呼び出しが困難になる。
    また、継承の場合ではそのクラスが必要としているメソッドを実装しているかを保証できない。
    ここでインターフェースを用いることで、implementsしたクラスは必ずそのメソッドをオーバーライド
    しなければならなくなるので、実装されていることが保証される。

    継承の場合は親クラスに必要の無いメソッドが定義されている場合はそのメソッドも引き継いでしまう。
    なので、インターフェースを実装することで必要なメソッドだけをオーバーライドし、実装することができる。
    ある意味必要の無い、呼び出されては困るメソッド、そのクラスには持たせておく必要の無いメソッドを
    呼び出されないことも保証しているということになるのかもしれない。

    参考になったサイト:
    http://www.gixo.jp/blog/5159
    http://oshiete.goo.ne.jp/qa/3166505.html
    http://oshiete.goo.ne.jp/qa/2031725.html
    http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11102595936

    • この返信は7年、 9ヶ月前にAtsushiが編集しました。
    #60
    t-isechi
    キーマスター

    自分もこの機会に、インターフェースと継承の役割を再度考えて見ます。
    多分に私見入ってるので、参考程度に。。。

    まずは、ポリモーフィズムとは何ぞやってところから。
    【ポリモーフィズム】
    操作を依頼する側は相手のオブジェクトのクラスを意識しなくても、異なる操作が実行される仕組み

    次にインターフェースと継承で、ポリモーフィズムを実現する場合ですが、

    ・インターフェース ⇒ 実現
    実現は、シグネチャ(操作名)のみで定義された実装のない抽象操作(抽象メソッド)を持つインターフェースと、それを実装するクラスとの関係。
    インターフェースを実装することにより、メソッドの使い方を統一することができる。
    また、インターフェースを実装したクラスのオブジェクトは、インターフェース型の参照変数に代入できるので、オブジェクトを意識することなくインターフェースを利用してメソッドを呼び出せる。

    ・継承       ⇒ 汎化
    汎化は、共通部分を表すクラスと詳細部分を表すクラス間における分類の関係。
    既存のクラスをもとに新しいクラスを作成することによって、クラスの再利用性を高めている。
    複数のサブクラスで、共通のスーパークラスのメソッドをオーバーライドすれば、操作を依頼する側はスーパークラスの定義でメソッドを呼び出せば、各サブクラスの実装の違いは意識しなくても呼び出されたオブジェクトによって異なる結果を得られる。

    どちらも特徴を理解して使いこなせば、メリットになるのは間違いないです。
    どちらで実現するかは場合次第って感じですが、システム開発の面で考えたときにはどうでしょう。

    システム開発の流れが以下だとします。
    ・企画作業
     開発するシステムのシステム構想を決定する

    ・要求分析作業
     顧客業務のデータや業務の流れを理解し、システムとしてどのような機能が必要であるかを抽出する

    ・仕様分析作業
     システム機能を実現するために、どのようなデータと処理が必要であるか、利用者の視点から明確にする

    ・方式設計作業
     システム機能をどのように実現するか、基本方針(開発言語,システムの構造,データベース)を決定する

    ・詳細設計作業
     仕様分析作業で明らかにしたデータと処理を、方式設計作業で決定した開発言語、システムの構造に従って、開発者の視点から実装ができるレベルまで詳細化する

    ・実装作業
     設計作業で詳細化したデータと処理に従って、オブジェクトを実装し、ソースコードを作成する。クラス単位または関連を持つクラス間の仕様を検証する

    ・結合テスト作業
     作成した全クラスを結合し、システムの処理が、仕様どおりに動作するかを検証する。

    ・システムテスト作業
     総合的なテストを行い、システムの処理が、仕様どおりに動作するかを検証する。

    こうして整理してみると、実装作業に入ってクラス間の仕様を決定するケースが一般的って言われてますね(実際はイレギュラーいっぱいあるだろうけど)。
    そういう意味ではJava言語における単一継承が、設計に大きく関わることになってくるから、継承でポリモーフィズムを実現する予定だったけど、実装中に顧客の追加注文や、思わぬ設計の落とし穴が見つかった際に、実現不可に陥るパターンもあるかもしれない。
    そのリスクを考えてポリモーフィズムはインターフェースメインで実現する方向で、実装が形になった段階で汎化できるところはまとめちゃうってのもありじゃないかな。

    企画作業の段階で、顧客にイメージを持ってもらうためにプロトタイピングで仮システムを作ることもあるだろうし、納期も絶対関わってくる以上は色々な状況に対応できる引き出しが必要ってことっすね。

    設計とか開発工程に関しては、今後も議論していきましょう。

3件の投稿を表示中 - 1 - 3件目 (全3件中)
  • このトピックに返信するにはログインが必要です。
タイトルとURLをコピーしました