多态如何替换循环内的if-else语句?

时间:2009-02-06 08:11:14

标签: language-agnostic oop loops polymorphism if-statement

多态如何在循环中替换if-else语句或Switch?特别是它总能取代if-else?我在循环中使用的大多数if-thens都是算术比较。这个问题是由question生成的。

int x;
int y;
int z;

while (x > y)
{
     if (x < z)
     {
         x = z;
     }
}

这对多态性有何影响?
注意:我用Java写了这个,但我对任何OOL感兴趣。

5 个答案:

答案 0 :(得分:25)

当每个案例对应不同类型时,多态性通常会替换switch语句。所以没有:

public class Operator
{
    string operation;

    public int Execute(int x, int y)
    {
         switch(operation)
         {
             case "Add":
                 return x + y;
             case "Subtract":
                 return x - y;
             case "Multiply":
                 return x * y;
             case "Divide":
                 return x / y;
             default:
                 throw new InvalidOperationException("Unsupported operation");
         }
    }
}
你有:

public abstract class Operator
{
    public abstract int Execute(int x, int y);
}

public class Add : Operator
{
    public override int Execute(int x, int y)
    {
        return x + y;
    }
}

// etc

但是,对于您提供的比较类型的决策,多态性确实无济于事。

答案 1 :(得分:3)

多态性在您提供的示例中并不适用。

请参阅此SO answer

答案 2 :(得分:3)

多态性只能在if测试基本上根据对象的“类型”调度到各种方法时进行测试。例如,如果对象是类型X,则调用foo,如果它是Y调用条等等。在这个人为的例子中,我们将使用方法bad()定义一个接口DoSonething。 X和Y都会实现Baz,并且它们各自的baz()为X调用foo(),为Y调用bar()。这简单地调用baz()将消除对if测试的需要。

答案 3 :(得分:3)

在Smalltalk中,“if”实际上是布尔值中的多态方法。在以下示例中:

[ x>y ] whileTrue:  
  [   
    ( x<z ) ifTrue: [ x:=z ]        
  ]

ifTrue:aBlock消息在True中实现为“执行此块”,在False中实现为“忽略此块”,因此取决于(x<z)的评估结果,将调用任一实现。

因此,在Smalltalk中,多态性默认替换每个if-else构造:)

答案 4 :(得分:1)

一种模式是具有表示测试结果的对象,以及表示要执行的块的对象。结果对象具有重写的选择函数,因此如果Bool有一个选择(T为正,T为负),则Bool.TRUE将返回正参数,而Bool.FALSE将返回负数。朴素家庭语言的天真实现就是这样。

要以该形式对while循环进行编码,需要在比较x和y的结果上调用choose方法来确定是否为while循环内部调用块,并且该块也使用compare并选择设置x的值。更直接的翻译是选择将x设置为z的块或不设置任何内容的块;相反,它只是使用选择将x设置回相同的值。

显然,对于这个简单的案例来说,这是过度的和低效的。

public class WantonPolymorphism {

    static class Int32 {
        final int value;
        Int32 ( final int value ) { this.value = value; }

        Compare compare ( Int32 other ) {
            // Java runs out of turtles at this point unless you use
            // an enum for every value
            if ( this.value < other.value ) return Compare.LESS;
            if ( this.value > other.value ) return Compare.GREATER;
            return Compare.EQUAL;
        }
    }

    enum Compare {
        LESS {
            <T> T choose (T less, T equal, T greater) { return less; }
        },
        EQUAL {
            <T> T choose (T less, T equal, T greater) { return equal; }
        },
        GREATER {
            <T> T choose (T less, T equal, T greater) { return greater; }
        };

        abstract <T> T choose (T less, T equal, T greater) ;
    }

    interface Block { Block execute () ; }


    /**
     * Main entry point for application.
     * @param args The command line arguments.
     */
    public static void main (String...args) {
        Block block =  new Block() {
            Int32 x = new Int32(4);
            Int32 y = new Int32(3);
            Int32 z = new Int32(2);

            public Block execute () {
                System.out.printf("x = %d, y = %d, z = %d\n", x.value, y.value, z.value);

                return x.compare(y).choose(done, done, new Block () {
                    public Block execute () {
                        x = x.compare(z).choose(x,x,z);

                        return x.compare(y).choose(done, done, this);
                    }
                });
            }

            Block done = new Block () {
                public Block execute () {
                    System.out.printf("x = %d, y = %d, z = %d\n", x.value, y.value, z.value);
                    System.exit(0);
                    return this;
                }
            };
        };

        for(;;) 
            block = block.execute();
    }
}