Generic type in Java

3

I have 3 classes, Expression , Operation , Scalar

public abstract class Expression<R extends Expression> {
    public abstract R calcular();
}

public abstract class Operation<T extends Expression, R extends Expression> extends Expression {
    protected T arg;
    public Operation(T arg) {
        this.arg = arg;
    }
    public T getArgumento() {
        return arg;
    }
}
public class Scalar extends Expression {
    private double valor;

    public double getValor() { }
    public void setValor(double valor) { }
    public Scalar(double valor) {
        this.valor = valor;
    }
    public Scalar calcular() {
        return this;
    }
}

What I want is to create the class to invert a scalar number, for example:

 public class InversaoEscalar extends Operation{
     public InversaoEscalar(Expression<Scalar> arg){
        super(arg);
     }
     public Scalar calcular(){
         return new Scalar(Parametro);
     }
 }

Being in Parametro I'd like to pass 1/arg.calcular().getValor() .

But I do not understand why arg.calcular() does not return an object of type Scalar , but of type Expression , since in my understanding, if I'm passing an argument of type Expression<Scalar> , the method calcular of it should bring me a type Scalar , right? How do I solve this problem?

    
asked by anonymous 14.05.2014 / 18:21

1 answer

5

You are inheriting without specifying the generic types:

Operation extends Expression -> R sem tipo
Scalar extends Expression -> R sem tipo
InversaoEscalar extends Operation -> T e R sem tipo

When you do not declare a type, the generic implementation uses a base type (in the case R extends Expression , so the base type of R will be Expression , if there was no upper bound explicit the type would be Object ).

Point solution:

Make Scalar be Expression<Scalar> (in this case calcular will return Scalar ).

class Scalar extends Expression<Scalar> 

Make InversãoScalar set at least type Expression<Scalar> to T ( arg will be of type T ), and any type of Expression to R that is not even being used: / p>

class InversaoEscalar extends Operation<Expression<Scalar>, Expression<?>> {

    public InversaoEscalar(Expression<Scalar> arg) {
        super(arg);
    }

    public Scalar calcular() {
        return new Scalar(1/arg.calcular().getValor());
    }
}

PS : Your solution is a bit generic and inherently loaded (the combination possibilities there make the use of the API complicated; even if you want to go down this path you will have to rethink your bounds and what should be parameterizable). I recommend you read this question: "Is it wrong to use class inheritance to group common behaviors and attributes?", As well as code from other libraries that deal with mathematical expressions in Java.

    
14.05.2014 / 18:42