18

ポリモーフィズムは、ループ内の if-else ステートメントまたは Switch をどのように置き換えることができますか? 特に、常に if-else を置き換えることができますか? ループ内で使用する if-then のほとんどは、算術比較です。この質問は、この質問から生まれました。

int x;
int y;
int z;

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

これはポリモーフィズムでどのように機能しますか?
注: 私はこれを Java で書きましたが、任意の OOL でこれに興味があります。

4

5 に答える 5

27

各ケースが異なるタイプに対応する場合、ポリモーフィズムは通常、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

ただし、提供した比較タイプの決定では、ポリモーフィズムは実際には役に立ちません。

于 2009-02-06T08:21:31.187 に答える
3

ポリモーフィズムは、if テストが基本的にオブジェクトの「タイプ」に応じてさまざまなメソッドにディスパッチされる場合にのみ、if テストを置き換えることができます。たとえば、オブジェクトがタイプ X の場合、Y の呼び出しバーの場合は foo を呼び出します。この不自然な例では、インターフェイス DoSonething をメソッド bad() で定義します。X と Y の両方が Baz を実装し、それぞれの baz() が X の場合は foo() を、Y の場合は bar() を呼び出すようにします。このように単純に baz() を呼び出すと、if テストが不要になります。

于 2009-02-06T08:25:30.617 に答える
3

Smalltalk では、「if」は実際には Boolean のポリモーフィック メソッドです。次の例では:

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

ifTrue:aBlockメッセージは「Trueこのブロックを実行する」および「Falseこのブロックを無視する」として実装されるため、評価結果に応じて(x<z)、いずれかの実装が呼び出されます。

したがって、Smalltalk では、ポリモーフィズムはデフォルトですべての if-else 構文を置き換えます :)

于 2009-02-06T09:19:43.097 に答える
3

あなたが提供した例では、ポリモーフィズムは実際には当てはまりません。

このSO answerを参照してください。

于 2009-02-06T08:19:39.850 に答える
1

1 つのパターンは、テストの結果を表すオブジェクトと、実行するブロックを表すオブジェクトを持つことです。結果オブジェクトは選択関数をオーバーライドしているため、Bool に choose(T positive, T negative) がある場合、Bool.TRUE は正の引数を返し、Bool.FALSE は負の引数を返します。smalltalk ファミリー言語の単純な実装は、そのように機能します。

while ループをその形式でエンコードするには、x と y を比較した結果に対して choose メソッドを呼び出して、while ループの内側のブロックを呼び出すかどうかを決定する必要があります。また、そのブロックは比較と選択を使用して、 x の値。より文字通りの翻訳は、x を z に設定するブロックまたは何もしないブロックのいずれかを選択することです。代わりに、choose を使用して 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();
    }
}
于 2009-02-06T10:18:56.833 に答える