Как Полиморфизм заменит оператор if-else внутри цикла?
Как полиморфизм может заменить инструкцию if-else или Switch внутри цикла? В частности, может ли он всегда заменять if-else? Большинство из if-thens, которые я использую внутри циклов, являются арифметическими сравнениями. Этот вопрос возникает из этого question.
int x;
int y;
int z;
while (x > y)
{
if (x < z)
{
x = z;
}
}
Как это работает с полиморфизмом?
ПРИМЕЧАНИЕ. Я написал это на Java, но я заинтересован в этом для любого OOL.
Ответы
Ответ 1
Полиморфизм обычно заменяет операторы 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
Однако для типа сравнения решения, которое вы предоставили, полиморфизм действительно не помогает.
Ответ 2
Полиморфизм на самом деле не применим в приведенном вами примере.
См. SO ответ.
Ответ 3
Полиморфизм может заменить только те тесты, когда тест if в основном отправляется на множество методов в зависимости от "типа" объекта. Например, если объект является типом X, вызовите foo, если он вызывает панель вызова и так. В этом надуманном примере можно было бы определить интерфейс DoSonething с методом bad(). И X, и Y будут реализовывать Baz и имеют свои соответствующие baz() вызовы foo() для X и bar() для Y. Это простое вызов baz() устранит необходимость в тесте if.
Ответ 4
В Smalltalk "if" на самом деле является полиморфным методом в буле. В следующем примере:
[ x>y ] whileTrue:
[
( x<z ) ifTrue: [ x:=z ]
]
Сообщение ifTrue:aBlock
реализовано в True
как "выполнить этот блок" и в False
как "игнорировать этот блок", поэтому в зависимости от того, что оценивает (x<z)
, будет вызываться реализация.
Таким образом, в Smalltalk полиморфизм по умолчанию заменяет каждую конструкцию if-else:)
Ответ 5
Один шаблон должен иметь объекты, которые представляют результат теста, и объекты, которые представляют собой блок для выполнения. Объекты результата имеют переопределенные функции выбора, поэтому, если у Bool был выбран (T положительный, отрицательный T), тогда Bool.TRUE вернет положительный аргумент, а Bool.FALSE вернет отрицательный результат. Наивные реализации небольших семейных языков работают так.
Чтобы закодировать цикл while в этой форме, необходимо вызвать метод select в результате сравнения x и y, чтобы определить, следует ли вызывать блок для внутреннего цикла while, и этот блок также использует сравнение и выбор для установки значения 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();
}
}
Ответ 6
Для примитива мы не можем, но для объекта да мы можем.
проверьте blog.