- PR -

オーバーライドについて

投稿者投稿内容
skt
会議室デビュー日: 2004/12/06
投稿数: 12
投稿日時: 2004-12-06 22:38
はじめて投稿します。よろしくお願いします。
下記のようなモジュール構成で、想定外の動作が発生し、
なぜそうなるのか悩んでおります。

<<環境>>
・Windows2000Pro
・WebSphere3.5
・JDK1.2.2


<<モジュール構成>>
public class 親 {
  public int getCount(){
    return 1000;
  }

}
public class 子1 extends 親 {

}
public class 子2 extends 親 {
  public int getCount(){
    return 5000;
  }
}

 親クラスでは getCount()メソッドが定義されており、戻り値1000を返します。
 子1クラスでは getCount()メソッドをオーバーライドしていません。
 子2クラスでは getCount()メソッドをオーバーライドしており、戻り値5000を返します。


public class クライアント1 {
  private static 子1 child1 = new 子1();
  public int getCount(){
    return child1.getCount();
  }
}
public class クライアント2 {
  private 子2 child2 = new 子2();
  public int getCount(){
    return child2.getCount();
  }
}
 クライアント1・クライアント2の各クラスは、子1、子2オブジェクトを保持しています。
 クライアント1は「private static」、クライアント2は「private」なフィールドです。

public class TestServlet extends HttpServlet {
  public void doPost(req,res){
    doGet(req,res);
  }
  public void doGet(req, res){
    int count = 0;
    if (req.getParameter("aaa").equals("1")){
      count = new クライアント1().getCount();  //1000のはず
    } else {
      count = new クライアント2().getCount();  //5000のはず
    }

    /* ここでreq.getParameter("aaa")の値をログ出力 */
    /* ここでcountの値をログ出力 */
  }
}


<<現象>>
WASを起動後の初回アクセスで、RequestParameter"aaa" が "1"のとき
→ count = クライアント1.getCount() = 1000となります。
2回目のアクセスで、RequestParameter"aaa"が "2"のとき、
→ count = new クライアント2().getCount() = 5000となる「はず」。
実際には2回目のアクセスでも1000が返ってきました。

なぜ2回目のアクセスで5000ではなく、1000が返ってきたのかがわかりません。


<<行ってみた対策>>
 クラス 子1 でもgetCountメソッドをオーバーライドする
  → 結果・・・上記現象は解決した


この現象がなぜ発生したのか、なぜ上記対策で解決したのか、
是非ご教授よろしくお願いします。
星野
会議室デビュー日: 2003/02/13
投稿数: 3
お住まい・勤務地: 茨城
投稿日時: 2004-12-07 00:21
原因は分かりませんが、
そのソースだと継承を使う意味がないように見えます。

コード:
public class TestServlet extends HttpServlet {
  public void doPost(req,res){
	doGet(req,res);
  }
  public void doGet(req, res){
	親 instance = null;
    if (req.getParameter("aaa").equals("1")){ 
      instance = new 子1();
    } else {
      instance = new 子2();
    }
    int count = instance.getCount(); 

    /* ここでreq.getParameter("aaa")の値をログ出力 */ 
    /* ここでcountの値をログ出力 */ 
  } 
}


とした方がより単純で、継承の意味も出てくると思います。

skt
会議室デビュー日: 2004/12/06
投稿数: 12
投稿日時: 2004-12-07 00:43
星野様
早速の返信ありがとうございます。

モジュール構成はかなり簡略化して書いたのですが、
実際は子クラスは10クラス(各々が約1500kstep)あり、
インスタンス生成は全てFactoryクラスに任せた構造になっています。
星野さんの案、もしくはクライアントクラスを1つにして、
public class クライアント1 {
  public int getCount(親 obj){
    return obj.getCount();
  }
}
と、親クラスを引数にとる構造も案としてはでているのですが、
ユーザテストで発覚したため、
原因を突き止めて現状を説明したいと考えております。

>原因は分かりませんが
私もなぜこうなるのかサッパリで・・・。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2004-12-07 00:45
引用:

    if (req.getParameter("aaa").equals("1")){
      count = new クライアント1().getCount();  //1000のはず
    } else {
      count = new クライアント2().getCount();  //5000のはず
    }



コード:
    if (req.getParameter("aaa").equals("1")){ 
      count = new クライアント1().getCount();  //1000のはず 
            System.out.println("client-1");
    } else { 
      count = new クライアント2().getCount();  //5000のはず 
            System.out.println("client-2");
    } 


にしたら、何が出力されますか?
skt
会議室デビュー日: 2004/12/06
投稿数: 12
投稿日時: 2004-12-07 01:01
かつのり様
ご返信ありがとうございます。

質問いただいた内容ですが、
>何が出力されますか?
というのは2回目のアクセス後のことですか?
でしたら "client-2" が出力されます。
もちろん、1回目のアクセス後は "client-1" が出力されます。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2004-12-07 01:08
2回目は下の処理を通過していると
思い込んでいるのではないかなと思って書き込みしました。。。
正しく下の処理を通過しているのいれば、原因は謎ですね。

クラスローダが悪さしているのかな・・・
takamaro
大ベテラン
会議室デビュー日: 2004/10/12
投稿数: 100
投稿日時: 2004-12-07 08:23
最初「メソッド名の記述ミスでオーバーライドしてるつもりが実際はしていないのでは」
と思ったのですが、、、

引用:

<<行ってみた対策>>
 クラス 子1 でもgetCountメソッドをオーバーライドする
  → 結果・・・上記現象は解決した




と、「子1」の修正で「子2」の出力結果が変わったという事なので違うようですね。
でも、「子2」の出力結果がおかしいのに「子1」の修正によって「子2」の出力結果
に変化が起きるというのは常識から考えても有り得る話ではありません。
かつのりさんが提案されたように、関係し得る全てのメソッドにSystem.out.println
等を用いた「通過チェック」を実装してみると何か見えてくるかもしれません。
それと多少気になったのは実行環境が1.2.2と古い事です。
古いから怪しいというわけでもないのですが、異なる実行環境下でも同様の結果に
なるのかどうか試してみると良いかもしれません。
tak3
ベテラン
会議室デビュー日: 2004/04/15
投稿数: 80
お住まい・勤務地: 菜の花・銀杏
投稿日時: 2004-12-07 10:29
引用:

引用:

<<行ってみた対策>>
 クラス 子1 でもgetCountメソッドをオーバーライドする
  → 結果・・・上記現象は解決した


と、「子1」の修正で「子2」の出力結果が変わったという事なので違うようですね。
でも、「子2」の出力結果がおかしいのに「子1」の修正によって「子2」の出力結果
に変化が起きるというのは常識から考えても有り得る話ではありません。


たしかに、ちょっと考えられませんね。
古いファイルでデプロイしてるっていうオチは?
子1クラスのgetCountをオーバーライドしないように元に戻すと、どうなりますか?

スキルアップ/キャリアアップ(JOB@IT)