-2

重複の可能性:
基本クラスに、オーバーライドされていない独自のメソッドを使用するように強制します

私がこれらのクラスを持っているとしましょう—申し訳ありませんが、ここで簡単な例を考えるのはちょっと難しいです。なぜ、やりたいのか、その答えは欲しくない!–:

class Squarer
{
    public void setValue(int v)
    {
        mV = v;
    }
    public int getValue()
    {
        return mV;
    }
    private int mV;
    public void square()
    {
        setValue(getValue() * getValue());
    }
}

class OnlyOddInputsSquarer extends Squarer
{
    @Override
    public void setValue(int v)
    {
        if (v % 2 == 0)
        {
            print("Sorry, this class only lets you square odd numbers!")
            return;
        }
        super.setValue(v);
    }
}

// auto s = new OnlyOddInputsSquarer();
OnlyOddInputsSquarer s = new OnlyOddInputsSquarer();
s.setValue(3);
s.square();

これは機能しません。をSquarer.square()呼び出すとsetValue()OnlyOddInputsSquarer.setValue()すべての値が拒否されます(すべての正方形が偶数であるため)。setValue()のすべての関数Squarerがそこで定義されたメソッドを引き続き使用するようにオーバーライドできる方法はありますか?

PS:申し訳ありませんが、Javaにはauto聞いたことのないキーワードがありません。私の側で希望的観測。

編集:変更できません Squarer

4

2 に答える 2

0

クラスSquarerはうまく設計されていないように私には思えます。これを機能させるために本当に汚いトリックが必要な場合は、メソッドをオーバーライドすることもできますsquare()

class OnlyOddInputsSquarer extends Squarer
{
    @Override
    public void setValue(int v)
    {
        if (v % 2 == 0)
        {
            print("Sorry, this class only lets you square odd numbers!")
            return;
        }
        super.setValue(v);
    }
    @Override
    public void square()
    {
        super.setValue(getValue() * getValue());
    }
}

しかし...奇数の平方は偶数ではないので、これは実際には問題にはならないはずです。これは単なる例であり、実際の問題は異なると思います。

編集: OK、これが機能しない場合は、さらに汚いメソッドがあります。setValueスタックをチェックし、代わりに呼び出しからsquare呼び出されたかどうかを確認します。super.setValue私はこれをお勧めしませんが、本当にこれを行う必要がある場合は、ここでその方法を確認してください。

于 2012-11-22T11:22:01.487 に答える
0

これは比較的痛みのない解決策だと思います。実際の二乗が完了するまでチェックを延期します。

public class OnlyOddInputsSquarer extends Squarer {

    @Override
    public void square() {
        if (getValue() % 2 == 0) {
            throw new IllegalStateException("Sorry, this class only lets you square odd numbers!")
        }
        super.square();
    }

}

そして、これがそのユニットテストです(JUnitが必要です):

public class OnlyOddInputsSquarerTest {

    @Test
    // normally this case would be in a separate test
    public void testSuperclass() {
        Squarer squarer = new Squarer();
        squarer.setValue(3);
        squarer.square();
        Assert.asserEquals(9, squarer.getValue());
    }

    @Test
    public void testOddValue() {
        OnlyOddInputsSquarer oddSquarer = new OnlyOddInputsSquarer();
        oddSquarer.setValue(3);
        try {
            oddSquarer.square();
            Assert.fail("Expected IllegalStateException");
        catch(IllegalStateException e) {
            // expected
        }
    }

    @Test
    public void testEvenValue() {
        OnlyOddInputsSquarer oddSquarer = new OnlyOddInputsSquarer();
        oddSquarer.setValue(4);
        oddSquarer.square();
        Assert.asserEquals(16, squarer.getValue());
    }

}
于 2012-11-22T11:52:50.200 に答える