-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());
    }
}

但是......奇数的平方不是偶数,所以这应该不是问题。我想这只是一个例子,你的真正问题是不同的。

编辑:好的,如果这不起作用,甚至还有一个更脏的方法:setValue检查堆栈以及它是否是从squarecall 调用的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 回答