Replace conditional with polymorphism, but how to do it [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Consider a following piece of code:
class NumberWrapper {
boolean negative;
void setNegativeTrue(boolean isNegative) {
negative = isNegative;
}
void negateNumber(int x) {
if (negative) {
x = x * -1;
} else {
x = Math.abs(x);
}
return x;
}
}
In code like this, how is it possible to use polymorphism ?

You can replace the boolean parameter which results in two different code paths with two different classes, each implementing one path.
abstract class Foo {
abstract void calculate(int x);
}
class NormalFoo extends Foo {
void calculate(int x) {
x = Math.abs(x);
return x;
}
}
class NegativeFoo extends Foo {
void calculate(int x) {
x = x * -1;
return x;
}
}
Instead of setNegativeTrue you create one of those classes and thereby replace the conditional with polymorphism

public enum UnaryOperator {
NEGATE {
#Override
public int apply(int x) {
return -x;
}
},
ABS {
#Override
public int apply(int x) {
return Math.abs(x);
}
}
public abstract int apply(int x);
}
class Foo {
private UnaryOperator operator = UnaryOperator.ABS;
void setUnaryOperator(UnaryOperator operator) {
this.operator = operator;
}
void calculate(int x) {
return operator.apply();
}
}

Related

Composing Function interfaces in Java

interface PairFloatFunction {
Pair<Float,Float> calculate(int x);
}
interface FloatFunction {
float calculate(int x);
}
class SQRT implements PairFloatFunction {
public Pair<Float, Float> calculate(int x) {
return new Pair(-pow(x,0.5), pow(x,0.5))
}
}
class ADD_ONE implements FloatFunction {
public Float calculate(int x) {
return x + 1;
}
}
I would like to compose to functions so that I can perfom this:
ADD_ONE(SQRT(100)) = Pair(-9,11)
I understand i need to 'glue' the functions together.
but I am stuck here, should I be writing another method overload that does this?
class ADD_ONE {
public Float calculate(int x) {
return x + 1;
}
public Float calculate(Pair pair) {
pair.first += 1;
pair.second += 1;
return pair
}
}
Sorry I am new to functional programming, is there a nice solution to this?
Based on your code above, I would create a generic interface which will be responsible for calculating.
interface Calculation<T> {
T calculate(int x);
}
This is a Java 7 implementation, because you did not specify Java 8.
Further Explanation
The return type T is generic; meaning that your implementation can return any Object type but it must consume an integer x. You could even make the x parameter generic so that you can decide what function will take as a parameter type.
Note: The static classes would be moved into their own class files and the static modifier should be removed. I only did this to consolidate everything for the sake of brevity.
Full Example
public class Functional {
static interface Calculation<T> {
T calculate(int x);
}
static class Sqrt implements Calculation<Pair<Float, Float>> {
public Pair<Float, Float> calculate(int x) {
float root = (float) Math.pow(x, 0.5);
return new Pair<Float, Float>(-root, +root);
}
}
static class AddOne implements Calculation<Float> {
public Float calculate(int x) {
return (float) (x + 1);
}
}
static <T> T calculate(int x, Calculation<T> calculation) {
return calculation.calculate(x);
}
public static void main(String[] args) {
Calculation<?>[] calculations = { new Sqrt(), new AddOne() };
int x = 49;
for (Calculation<?> calculation : calculations) {
System.out.printf("%s: %s%n",
calculation.getClass().getSimpleName(),
calculate(x, calculation));
}
}
static class Pair<T, U> {
private T val1;
private U val2;
public Pair(T val1, U val2) {
this.val1 = val1;
this.val2 = val2;
}
protected T getVal1() {
return val1;
}
protected void setVal1(T val1) {
this.val1 = val1;
}
protected U getVal2() {
return val2;
}
protected void setVal2(U val2) {
this.val2 = val2;
}
#Override
public String toString() {
return "(" + val1 + ", " + val2 + ")";
}
}
}
Output
Sqrt: (-7.0, 7.0)
AddOne: 50.0

Getting max value from object in an abstract class array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I´ve been trying to solve this.
I wanted to get max ClassA value.
So I have an interface and 2 classes
public interface Something {
}
public class ClassA implements Something{
private int a;
public ClassA(int a) {
this.a = a;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
public class ClassB implements Something{
private int b;
public ClassB(int b) {
this.b = b;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
}
public class Program {
public static void main(String[] args) {
Something[] array = new Something[10];
array[0] = new ClassA(1);
array[1] = new ClassA(2);
array[2] = new ClassB(0);
ClassA max = null;
for (int i = 0; i < array.length; i++) {
if(array[i]!=null && array[i] instanceof ClassA){
//what do to here
}
}
}
}
I thought that I put this there,
if(array[i].getClassA()>max.getClassA()){
max = array[i];
}
but its not working, so what should I do to make it working ?
Thanks for answers.
I am guessing the code doesn't even compile. This is because it is not enough to determine an object is a type, you have to cast the reference to access it's methods or fields.
ClassA a = (ClassA) array[i];
if (a.getA() > max.getA())
max = a;
BTW This is not an example of Polymorphism as you are not using an overridden method here.
An example using polymorphism might look like
interface Something {
boolean isA();
int getA();
}
class ClassA implements Something {
// fields and constructor
public boolean isA() { return true; }
public int getA() { return a; }
}
Something[] array = { new ClassA(1), new ClassA(2), new ClassB(0) };
ClassA max = null;
for (Something s : array) {
if (s.isA()) {
if (max == null || max.getA() < s.getA())
max = s;
}
}
Do a null check on max and then compare the values
for (int i = 0; i < array.length; i++)
{
if(array[i]!=null && array[i] instanceof ClassA){
if (max == null || array[i].getA() > max.getA()){
max = array[i];
}
}
}

Converting Types into other Types [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
What I'm trying to do is to get this line of code to work in my main method:
Expression exp = new Add(new Value(3.2), new Multiply(new Value(4.1),
new Value(7.1)));
Here's my code:
public interface Expression {
public int accept(EvaluationVisitor visitor);
}
My Operation Class
public class Operation implements Expression {
private Expression lhs;
private Expression rhs;
public Operation(Value lhs, Value rhs)
{
this.lhs = lhs;
this.rhs = rhs;
}
public Expression getLHS()
{
return lhs;
}
public Expression getRHS()
{
return rhs;
}
public int accept(EvaluationVisitor visitor) {
return 0;
}
}
Value Class(represents a float value):
public class Value implements Expression {
private float number;
public Value(float number)
{
this.number = number;
}
public String toString()
{
return String.valueOf(number);
}
public float getValue()
{
return number;
}
public int accept(EvaluationVisitor visitor) {
return 0;
}
}
My Add and Multiply methods:
public class Add extends Operation {
private Value lhs;
private Value rhs;
public Add(Value lhs, Value rhs)
{
super(lhs,rhs);
}
public String toString()
{
return String.valueOf(lhs.getValue() + rhs.getValue());
}
public Value add()
{
return new Value(lhs.getValue() + rhs.getValue());
}
}
public class Multiply extends Operation{
private Value lhs;
private Value rhs;
public Multiply(Value lhs, Value rhs)
{
super(lhs,rhs);
}
public String toString()
{
return String.valueOf(lhs.getValue() + rhs.getValue());
}
public Value mul()
{
return new Value(lhs.getValue() * rhs.getValue());
}
}
Here's the line of code again:
Expression exp = new Add(new Value(3.2), new Multiply(new Value(4.1),
new Value(7.1)));
In my line of code that I'm trying to get to work, I want to find a way that the Multiply object can be a value can be taken in as an argument. I know that I could just create the object and then place it there by calling my method that returns a Value object, but a constructor is supposed to set up an object so the state of the object is valid. Is there anyway I could get around this?
You need to make full use of your interface so you can treat the values and operator expressions indiscriminately. Right now you aren't doing that, for example, Operation which takes two Values as arguments but stores them as Expressions.
You also have a problem which is that your subclasses of Operation are declaring duplicate members named lhs and rhs. Perhaps you've already noticed that right now you'll get null pointer exceptions if you try to call methods on Add and Multiply.
Here is a slight redesign:
public interface Expression {
public Value evaluate();
}
public class Value implements Expression {
private final float floatValue;
public Value(float floatValue) {
this.floatValue = floatValue;
}
public float floatValue() {
return floatValue;
}
#Override
public Value evaluate() {
return this;
}
}
public abstract class BinaryOperator implements Expression {
protected final Expression lhs, rhs;
public BinaryOperator(Expression lhs, Expression rhs) {
this.lhs = lhs;
this.rhs = rhs;
}
}
public class Add extends BinaryOperator {
public Add(Expression lhs, Expression rhs) {
super(lhs, rhs);
}
#Override
public Value evaluate() {
return new Value(
lhs.evaluate().floatValue()
+
rhs.evaluate().floatValue()
);
}
}
public class Multiply extends BinaryOperator {
public Multiply(Expression lhs, Expression rhs) {
super(lhs, rhs);
}
#Override
public Value evaluate() {
return new Value(
lhs.evaluate().floatValue()
*
rhs.evaluate().floatValue()
);
}
}
Now you can do
Expression exp = (
new Add(new Value(3.2f), new Multiply(new Value(4.1f), new Value(7.1f)))
);
System.out.println(exp.evaluate().floatValue());
Which outputs 32.309998 (the correct answer).
The above redesign could be further simplified if evaluate simply returned a float.
The constructors take Value objects but Multiply does not extend Value
What you are doing is adding a value to an operation. What you really want to be doing is adding a value to a value (the latter being the result of an operation). So you should do the following:
Expression exp = new Add(new Value(3.2), new Multiply(new Value(4.1),
new Value(7.1)).mul());
Alternatively, you could make your Operation class extend Value and override the getValue() method inside the Multiply class to perform the multiplication and return the value (likewise in the Add class to perform the addition and return the value).

relation between two classes (german code) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I want to make an array with which I can create some instances of the class Schiff (Ship) by using the class Flotte (Armada). Somehow it does not work. Which method is more useful? addShiff or addSchiff2?
public class Schiff
{
private String material;
private int kanonen;
private int ursprungsMäste;
private int mästeStehenNoch;
public Schiff (String material, int kanonen, int mäste)
{
this.material = material;
this.kanonen = kanonen;
ursprungsMäste = mäste;
mästeStehenNoch = mäste;
}
public String gibMaterial()
{
return material;
}
public void mastGetroffen(int wieVieleTreffer)
{
mästeStehenNoch = mästeStehenNoch - wieVieleTreffer;
}
public void wieVieleMäste ()
{
System.out.println("Es stehen noch " + mästeStehenNoch + " Mäste!");
}
}
+++++++
public class Flotte
{
private Schiff [] flottenArray;
public Flotte ()
{
flottenArray = new Schiff [100];
}
public void addSchiff (String material, int kanonen, int ursprungsMäste)
{
for (int zahl = 0; zahl<flottenArray.length; zahl++)
{
if (flottenArray[zahl] == null)
{
flottenArray[zahl] = new Schiff (material, kanonen, ursprungsMäste);
}
}
}
public void addSchiff2 (Schiff neuesSchiff)
{
for (int zahl = 0; zahl<flottenArray.length; zahl++)
{
if (flottenArray[zahl] == null)
{
flottenArray[zahl] = neuesSchiff;
}
}
}
public void gegnerischerFeuerAngriff ()
{
for (Schiff schiff : flotte)
{
if (schiff.gibMaterial().equals("holz"))
{
flottenArray.remove(schiff);
}
}
}
}
What exactly does not work?
Looks good to me.
My feeling is that you can drop the addSchiff (String material, int kanonen, int ursprungsMäste) method because:
One: It is just another way of writing addSchiff2(new Schiff(material, kanonen, ursprungsMäste)) and this is also how it should be coded to avoid repeating yourself:
public void addSchiff (String material, int kanonen, int ursprungsMäste)
{
addSchiff2(new Schiff(material, kanonen, ursprungsMäste))
}
Two: If you later decide to add fields to class Schiff you will have to change the interface of Flotte if you keep the method that constructs a Schiff instance from passed parameters. This is not the case if you just have a method that takes a Schiff instance. So getting rid of addSchiff() decreased inter-class coupling, which is gut.
Klar zur Halse!

How to get arithmetical operators at runtime?

How I can get arithmetical operators at run-time in Java? Suppose if I have values
ADD it should add the number
MUL then it should multiply the number
For Example
public calculate(int x, String str){
while(str.equals("some value")){
If( str.equals("ADD"))
// it should return me something like x+
if( str.equals("MUL"))
it return me something like x*
}
if( str.equals("FINAL"))
it should return me x+x*x
}
What you need is not runtime metaprogramming, but first class functions.
The following represent first class functions, with arity 1 and 2 respectively.
abstract class UnaryFunction<A, B> {
public abstract B apply(A a);
}
abstract class BinaryFunction<A, B, C> {
public abstract C apply(A a, B b);
}
For the sake of simplicity, let's use specialized versions of above classes.
abstract class UnaryOperation {
public abstract int apply(int a);
}
abstract class BinaryOperation {
public abstract int apply(int a, int b);
}
Now construct a dictionary of the required arithmetic operations.
Map<String, BinaryOperation> ops = new HashMap<String, BinaryOperation>();
ops.put("ADD", new BinaryOperation() {
public int apply(int a, int b) {
return a + b;
}
});
ops.put("MUL", new BinaryOperation() {
public int apply(int a, int b) {
return a * b;
}
});
// etc.
Add a method that partially applies BinaryOperation on one parameter.
abstract class BinaryOperation {
public abstract int apply(int a, int b);
public UnaryOperation partial(final int a) {
return new UnaryOperation() {
public int apply(int b) {
return BinaryOperation.this.apply(a, b);
}
};
}
}
Now we can write your calculate method.
public UnaryOperation calculate(int x, String opString) {
BinaryOperation op = ops.get(opString);
if(op == null)
throw new RuntimeException("Operation not found.");
else
return op.partial(x);
}
Use:
UnaryOperation f = calculate(3, "ADD");
f.apply(5); // returns 8
UnaryOperation g = calculate(9, "MUL");
f.apply(11); // returns 99
The abstractions used in the above solution, namely first class function interfaces and partial application, are both available in this library.
public class Calculator {
public static enum Operation {ADD, MUL, SUB, DIV};
private int x; // store value from previous operations
public void calculate(int x, Operation operation) {
switch(operation) {
case ADD:
this.x += x;
break;
case MUL:
this.x *= x;
break;
case SUB:
this.x -= x;
break;
case DIV:
this.x /= x;
break;
}
}
public int getResult() {
return this.x;
}
}
To use it elsewhere in your code:
public static void main(String[] args) {
Calculator c = new Calculator();
c.calculate(4, Calculator.Operation.ADD);
// Other operations
c.getResult(); // get final result
}
Assuming you are trying to just add and multiply x, just do the following:
public int calculate(int x, String str) {
// while(true) is gonna get you into some trouble
if( str.equals("ADD")) {
return x + x;
}
else if( str.equals("MUL")) {
return x * x;
}
else
return x; // not sure what you want to do in this case
}

Categories

Resources