- - PR -
あるクラスの paint メソッド内でサブクラスの paint メソッドを呼びたい
1|2|3|4|5
次のページへ»
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-07-03 17:04
unibon です。こんにちわ。
#以下、例として AWT を挙げていますが、それはあくまでも例であり、 #疑問点としては Java の言語仕様(やオブジェクト指向的な考え)に関することです。 Java のメソッド(たとえば AWT の Canvas クラスの paint メソッド)内で 自身のクラスのスーパクラスのメソッドである super.paint を呼ぶことができますが、 逆にサブクラスの paint メソッドを呼ぶことはできるでしょうか。 sub.paint みたいな感じで。 たとえばですが AWT の Canvas クラスを継承して、 paint メソッドでの描画が5倍に拡大されるようなことを目論んだとします。 つぎのように作るととりあえず動きました。 --- MyCanvasTester.java ---
しかし、これだと新しく paint2 というメソッドを作らないといけないのですが、 本当はこのようなことを実現するのに、paint2 を使わずに、 つぎのように paint メソッドだけを使ったコードにしたいと思っています。
このようなことはたぶん、無理なのだとは思いますが、 これはオブジェクト指向的にヘンな考えなのか、 それとも単に Java にそういう仕組みがないだけなのでしょうか。 疑問なのは、paint メソッドから別のメソッド(foo)は呼ぶことができるので、 サブクラスで foo メソッドをオーバライドすることで、 あるクラスの paint メソッドから、そのサブクラスの foo メソッドを呼ぶことができます。 これと同じようなことが同名のメソッドだとできない、 すなわち、あるクラスの paint メソッドからサブクラスの paint を呼べないのは、 なぜなのでしょうか。 | ||||||||
|
投稿日時: 2003-07-03 18:13
田村と申します
abstract class MyCanvas extends Canvas { // template method protected abstract void paintsub(Graphics canvasGraphics); .... public void paint(Graphics canvasGraphics) { // 共通部分を記述 .... paintsub(canvasGraphics); // sub-classで実装 // 共通部分を記述 ... } } 上述したコードのように、Templete Method パターンで記述する方法ではだめでしょうか?メソッドの名前は変わってしまいますが、同様の事を行えることができると思います。 | ||||||||
|
投稿日時: 2003-07-03 21:26
こんにちは。
このスレッドを読んでまず思ったこと。 1.サブクラスでスーパークラスと同一名メソッドを書いた時点でオーバーライトになり 同一名のメソッド呼び出しはサブクラスのものから呼び出されるので、スーパークラス の同一名メソッドを先に呼び出すのは無理では? 2.仮にスーパークラスが、サブクラスの同一名メソッドを呼び出せる仕組みになっていた 場合、それを知らずにサブクラスからスーパークラスの同一名メソッドを呼び出す ソースを書いた場合、お互い呼び出しあってアウトオブメモリーで落ちるので危険? ではないでしょうか? | ||||||||
|
投稿日時: 2003-07-03 21:36
以下のようにインターフェースを使って無理やり、スーパークラスからサブクラスの同一
名メソッドを呼び出すようにしたのですが、そもそもサブクラスの方を先によぶので スーパークラス側のメソッドは呼び出されませんでした。あたりまえか・・・。 ちなみに、サブクラスでスーパークラスの同一名メソッドをインターフェースのメソッド として実装しても、スーパークラスの同一名メソッドであればスーパークラスのオーバー ライトとして扱われるようですね。 import java.awt.*; class MyCanvas extends Canvas { private MyCanvasEvents evnts; public MyCanvas(){ super(); } public void setEvents( MyCanvasEvents evnts ){ this.evnts = evnts; } public void paint(Graphics canvasGraphics) { super.paint(canvasGraphics); Image image = createImage(100, 100); Graphics imageGraphics = image.getGraphics(); evnts.paint(imageGraphics); imageGraphics.dispose(); canvasGraphics.drawImage(image, 0, 0, 500, 500, this); System.out.println("SUPER"); } } public class MyCanvasTester extends MyCanvas implements MyCanvasEvents{ public MyCanvasTester(){ super(); setEvents(this); } public void paint(Graphics graphics) { super.paint(graphics); graphics.setColor(Color.blue); graphics.drawLine(0, 0, 100, 100); System.out.println("SUB"); } public static void main(String[] args) { Frame frame = new Frame(); Canvas canvas = new MyCanvasTester(); frame.add(canvas); frame.setSize(new Dimension(600, 600)); frame.setVisible(true); } } interface MyCanvasEvents{ public void paint(Graphics graphics); } | ||||||||
|
投稿日時: 2003-07-03 22:08
unibon さん、こんにちは。
スーパークラスからサブクラスのメソッドを呼ぶことは、同名じゃなくても出来ないんじゃ ないでしょうか。下記のコードで試してみました。(ファイル名:PrintTest.java)
ソースコード上、スーパークラスのprinter()がサブクラスのprinting2()を呼んでいるように 見えますが、結果は同じサブクラス内で処理されてました。 | ||||||||
|
投稿日時: 2003-07-03 23:31
たぶん、継承の概念の基本として「子は親を知っているが、親は子を知らない」ということがあるからだと思います。Javaは型の縛りが強い言語なので、定義されていないものを参照しようとしてもコンパイルが通らない。そして、存在するかどうかもわからないサブクラスのメソッドは呼び出せない(paintメソッドをサブクラスが実装してくれるという保証は"普通は"ないわけですから) ……とはいえ、下記のようなコードだったら、サブクラスでの実装が保証されるわけだから問題ない気もします。どなたかこのようなコードが規制されなければならない理由とか知っていたら教えてください(^_^;
ひとつ理由として思いつくのは、maruさんが言っているように、サブクラスのpaintメソッドでsuper.paintを呼ぶと無限ループに陥ること。でも、それは言語仕様で禁止するという方法もあるわけで…… [ メッセージ編集済み 編集者: 英-Ran 編集日時 2003-07-04 00:05 ] | ||||||||
|
投稿日時: 2003-07-03 23:39
sub.paint()ができるようにしたら、ポリモーフィズム(多態性)ができなくなってしまうと思います。
| ||||||||
|
投稿日時: 2003-07-03 23:51
すみません、abstractと書いてしまったために誤解を招いてしまったような気がします。意図としては、「サブクラスのメソッドよりスーパークラスのメソッドを先に呼ぶ」という逆オーバーライド的な機能を実現すると言うつもりでした。 # そのためにはabstractではない別のキーワードが必要ですね…… [ メッセージ編集済み 編集者: 英-Ran 編集日時 2003-07-03 23:53 ] |
1|2|3|4|5
次のページへ»