覆盖java方法而不影响父行为

时间:2012-11-22 10:56:03

标签: java oop override

  

可能重复:
  force base class to use its own method and not overrided method

假设我有这些课程 - 抱歉,这里很难想到一个简单的例子;我不想要任何为什么 - 你想要做的答案! - :

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

2 个答案:

答案 0 :(得分:0)

在我看来,Square Square并没有很好的设计。如果你真的需要一个肮脏的技巧来使这项工作,你也可以覆盖方法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中检查堆栈以及是否从square调用{ {1}}而是。我不建议这样做,但如果真的非常需要完成此操作,check here to see how to do it.

答案 1 :(得分: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());
    }

}