• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:【継承】親のメソッドの実行)

【継承】親のメソッドの実行

このQ&Aのポイント
  • C++、VB.net、Java、Delphiなどのオブジェクト指向言語において、子クラスのrunメソッドを実行したとき、「親」と表示された後に「子」と表示される場合と、「子」とのみ表示される場合がある。
  • 特に子クラスでsuper.runと書く必要がない言語が多く、自動的に親のメソッドが呼び出される場合が多い。
  • ただし、C++では子クラスで明示的に親の同名メソッドをコールしなければ処理が実行されないため、C++の仕様は他の言語と異なる少数派である可能性がある。

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

  • ベストアンサー
回答No.2

派生クラスで基底クラスの関数を上書きした場合は、派生クラスで定義された動作になります。 従って、答えは(2)になります。 基底クラスの動作を残しつつ派生クラスの処理を追加したい場合は、 普通はテンプレートメソッドを適用して基底クラスを設計します。 ただし、仮想になっていないメソッドを上書きするとポインタまたは参照の型によって動作が変わります。 いずれにせよ、明示的に書かない限り(1)の動作はしません。

TeferiMage
質問者

お礼

ありがとうございます。 (#6の方にてお礼申し上げます)

TeferiMage
質問者

補足

C++では、同名メソッドを書くとオーバーライドになるんですね。 驚き&意外です。 子側の関数で、 superclass::run を書く方法以外で、 メソッドの継承はできないのでしょうか??

その他の回答 (6)

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.7

>私が触ってきた言語では、通常、 >何も書かなくても親の処理が実行され、 >子側では、差分だけ、同名メソッドに追記するだけでよいということが多かった気がします。 それが何という言語なのか、興味ありますね。その言語では、下記のような場合にどうやって記述するのでしょう。 [A]親クラスのrunメソッドと全く違うことを子クラスのrunメソッドでやりたい(コンソールに「親」と表示したくない)場合 [B]コンソールに「子」と表示してからコンソールに「親」と表示したい場合 super.run()を明示的に書く言語(C++とかJava)では[B]は明らかですし、[A]もsuper.run()を書かないだけで実現できます。

TeferiMage
質問者

お礼

子側のクラスで「このメソッドはオーバーライドします」と書くと、継承上書きできる仕様でした。 デフォルトが、処理の継承(※処理の追加)で、明示的に継承上書きと書くと、継承上書きになったと記憶しています。 どの言語だったかは覚えていないのですが、 古めのバージョンのpowerbuilderだったような気がします。 でも、皆さんから突っこまれて、なんか記憶に自信がなくなってきました。。

回答No.6

#2です。 >子側の関数で、 >superclass::run を書く方法以外で、 >メソッドの継承はできないのでしょうか?? 先に申し上げたとおり、テンプレートメソッドを使います。 // public Base::Run() {  // 基底クラスでの処理  ・・・  // 派生クラスの処理を呼び出す  OnRun() } // protected Derived::OnRun() {  // 派生クラスでの処理 } OnRun関数は仮想関数にして、基底クラスでは何も処理しないで定義します。 実際に行いたい処理を派生クラスで定義します。 派生クラスのインスタンスからRun関数が呼ばれると、 基底クラスのRun関数内の処理が行われた後、派生クラスのOnRun関数が実行されます。 このようなデザインパターンはC++だけでなく、 Java, C#, VB.NETいずれのオブジェクト指向言語でも適用でき、 潰しが利いて大変便利です。 是非とも身に付けられることをお勧めします。

参考URL:
http://ja.wikipedia.org/wiki/Template_Method_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3
TeferiMage
質問者

お礼

ありがとうございます。 テンプレートメソッドは、以下のようなときだけ使っていました。 ordered_process { step1; step2; } step1{ } step2{ } /*************************/ 例を出して頂いて気づきましたが、 確かに、 step1は親のメソッドにしか実装せず、 逆にstep2を子だけにしか実装しないようにすれば、 (ordered_processをパブリック、step1をprivateにして隠蔽、step2をprotected) 「通常、何も書かなくても親の処理が実行される」 はできそうですね! ありがとうございます。

回答No.5

> 私が触ってきた言語では、通常、何も書かなくても親の処理が実行され、 > 子側では、差分だけ、同名メソッドに追記するだけでよいということが多かった気がします。 その「差分だけ追記」というのが、ちょっと気になります。 あるクラスが100個のメソッドを持っていて、その殆どを使いまわしつつ幾つか機能を追加したクラスを新たに作りたい、というようなケースで、 「継承」の概念を用いて親のメソッドをほとんどそっくり貰ってきて、足りない分は子に追記する、というのが、オブジェクト指向で「差分を追記」と言った場合の意味合いに通常なります。 行単位・文単位ではなく、メソッド単位の追加なんです。 そこが不思議でならないのですが・・・ >#4 > C++にしろ、smalltalkにしろ、自分がぱっと思い当たるもので、上記挙動をする言語はないような。 私も同感です。ちょっと聞いたことがない。Common Lispなんかの例外中の例外を除けば。

TeferiMage
質問者

お礼

う~ん、#4さんも、#5さんも仰っているということは、 私の勘違いだったのかもしれません。 ありがとうございます。 (時間があれば、色んな言語で再確認してみたいと思います。)

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.4

回答じゃないけど、 > 私が触ってきた言語では、通常、何も書かなくても親の処理が実行され、 > 子側では、差分だけ、同名メソッドに追記するだけでよいということが多かった気がします。 C++にしろ、smalltalkにしろ、自分がぱっと思い当たるもので、上記挙動をする言語はないような。 具体的にどの言語が、そのような挙動を示すか、補足したほうが回答が得られやすいと思います。

TeferiMage
質問者

お礼

ありがとうございます。 どの言語でそうだったか、書ければ書きたかったのですがうろ覚えで書けませんでした... (vb.netか、powerbuilderか、javaか、delphiのどれかだったとは思うのですが。)

回答No.3

#1です。 > 継承のためには、以下のように書くケースが多いということでしょうか? あなたの言う「継承」の意味がはっきりしないのですが、子クラスが存在する理由は「親クラスとは微妙に違うことをやりたい」という点にあるので、一般に、親クラスの同名メソッドが勝手に実行されては困ります。 例えば、次の例を考えてみてください。 親クラス:車  accelメソッド   自身の速度を5[m/s]上昇させる 子クラス:トヨタの何とかっていう車、親クラスは「車」  accelメソッド   自身の速度を10[m/s]上昇させる この場合、子クラスのaccelメソッドを呼び出した時に自動的に親クラスが呼び出されてしまうと、「そこ書いてあること」と「実際に起こること」との間に差が生まれてしまい、可読性を損なう等の問題が発生します。 その為、「わざわざ親クラスを呼び出したい」という場合には、「わざわざそう指定してやる必要がある」というのが、多くの言語でよく採られている方式です。 又、子クラスに「自身の親クラスはhoge型」だと明示するのは、親子関係を生じさせる時点で既にやっていることのように思えます。色々と無駄です。

TeferiMage
質問者

お礼

ありがとうございます。 「親クラスとは微妙に違うことをやりたい」で目的は合っていますが、 私が触ってきた言語では、通常、 何も書かなくても親の処理が実行され、 子側では、差分だけ、同名メソッドに追記するだけでよいということが多かった気がします。 なので、今のところ、C++では、 子側の関数で、 superclass::run を書く方法で考えています。 私は、 親クラス:車  speedプロパティ   x  accelメソッド   自身の速度をx[m/s]上昇させる 子クラス:トヨタの何とかっていう車、親クラスは「車」  accelメソッド   (※何も書かなくても、自身の速度をx[m/s]上昇させる)   速度を上昇した後に行う処理を、追記しておく。 という記述方式の言語が多かったです。 (superclass::accelを書く必要がなかったです)

回答No.1

一言で言うと、言語によって違う、ということになります。 又、一般のメソッドと一部の(コンストラクタのような)メソッドとでも違いが生まれます。 ただし、この場合では、「親クラスのrunメソッドが子クラスによってオーバーライドされている」という扱いになるでしょうから、理屈の上では、親クラスのrunメソッドは「呼ばれない」方が正しい実装になるかと思われます。

TeferiMage
質問者

お礼

ありがとうございます。 上の方のご回答でお礼申し上げます。

TeferiMage
質問者

補足

ありがとうございます。 継承のためには、以下のように書くケースが多いということでしょうか? 親クラス   runメソッド     コンソールに「親」と表示 子クラス : 親クラスはhoge型   runメソッド : 親クラスはhoge型     コンソールに「子」と表示

関連するQ&A