3

まず、既存のクラス構造を拡張しており、オリジナルを変更することはできません。

私はこれをしたいと思います:

class a
{
   int val;

   ... // usual constructor, etc...

   public int displayAlteredValue(int inp)
   {
     return (val*inp);
   }
}

class b extends a
{
   ... // usual constructor, etc...

   public in displayAlteredValue(int inp1, int inp2)
   {
     return (val*inp1*inp2);
   }
}

前に言ったように、変更することはできず、新しい関数を作成するのではなくclass a、関数名を維持したいと考えています。displayAlteredValueこれができれば、 のいくつかのインスタンス化を のaインスタンス化に変更するだけで済みますb。への多くの関数呼び出しを置き換えるのに多くの時間を費やしたくありませんdisplayAlteredValue。(そして、はい、検索と置換などがあることは認識していますが、他の理由でそれを行うと問題が発生します)。

何か案は?

4

7 に答える 7

3

派生クラスで関数をオーバーロードできます。したがって、上記で指定したものが機能するはずです。簡単なテストを書いただけでうまくいきました。

public class DerivedOverload {

    /**
     * @param args
     */
    public static void main(String[] args) {
        A classA = new A(); 

        B classB = new B();

        System.out.println("DerivedOverload.main() classA.displayAlteredValue(2) : " + classA.displayAlteredValue(2));

        System.out.println("DerivedOverload.main() classA.displayAlteredValue(2) : " + classB.displayAlteredValue(2,2));
    }



}


class A
{
   int val = 2;

   A(){

   }

   public int displayAlteredValue(int inp)
   {
     return (val*inp);
   }
}

class B extends A
{
   B(){

   }

   public int displayAlteredValue(int inp1, int inp2)
   {
     return (val*inp1*inp2);
   }
}

システムアウト。DerivedOverload.main() classA.displayAlteredValue(2): 4 DerivedOverload.main() classA.displayAlteredValue(2): 8

于 2008-11-12T20:44:53.280 に答える
2

問題が何であるかはわかりません。同じ名前で署名が異なるメソッドを持つサブクラス b を絶対に作成できます。

実行している可能性のある問題の 1 つは、b にのみ存在するメソッドを呼び出すために、オブジェクトの型が a ではなく b であることをコンパイラが認識する必要があることです。

したがって、次のようなコードは機能しません。

// this works because b is a subclass of a
a anObject = new b();

// this will not compile because the declared type of anObject is a
int x = anObject.getValue( 1, 2 );

変数の宣言を b 型に変更するか、引数が 2 つのメソッドを呼び出すときはいつでも変数を b にキ​​ャストする必要があります。

于 2008-11-12T20:46:13.607 に答える
1

または、拡張するクラスが別のパッケージからのものであるため、継承よりもコンポジションを優先することを検討できます。

http://www.artima.com/lejava/articles/designprinciples4.html

于 2008-11-12T21:02:44.120 に答える
1

これを派生クラスに追加するとどうなりますか

public int displayAlteredValue(int inp)
{
  return super.displayAlteredValue(inp);
}
于 2008-11-12T20:36:07.213 に答える
1

記述したコードはそのままコンパイルされます。基本的に、メソッドをオーバーロードしました。投稿したコードで達成できないこと、達成したいことは何ですか? 人々が単一の引数で b.displayAlteredValue を呼び出すのを止めようとしていますか? もしそうなら、リスコフの代用可能性原則に違反するので、(コンパイル時に) それを行うことはできません。

例外をスローすることはできますが、それはあまり良いことではありません。

別の方法として、継承の代わりに構成を使用することもできますが、それが適切かどうかを判断するには、状況について詳しく知る必要があります。

于 2008-11-12T20:45:43.357 に答える
1

あなたが持っているものは私にはうまく見えます。

クラス b のインスタンスは、メソッドの両方のバージョンにアクセスできます。引数が 1 つのバージョンへの呼び出しは、自動的にクラス a にルーティングされます。引数が 2 つのバージョンへの呼び出しは、クラス b に移動します。

ただし、クラス a のインスタンスは 1-arg バージョンにしかアクセスできませんが、それを回避する方法はないと思います。

于 2008-11-12T20:45:51.797 に答える
0

クラス B のコードは次のように記述できます。

public int displayAlteredValue(int inp) 
{
    return -1;
}

-1 がエラーを返すことを関数に示します。int の場合、これは実際には機能しませんが、クラスを返した場合、メソッドの単一パラメーター バージョンを呼び出すと、null を返すことができます。

于 2008-11-12T20:56:41.807 に答える