Generic type in Java

Asked

Viewed 180 times

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 of inverting a scalar number, for example:

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

Whereas in Parametro I’d like to pass 1/arg.calcular().getValor().

But I don’t understand why arg.calcular() does not return me an object of type Scalar, and yes of the type Expression, since in my understanding, if I am passing a argument of the type Expression<Scalar>, the method calcular He should bring me a guy Scalar, no? How to solve this problem?

  • 1

    se eu estou passando um arg do tipo Expression, o metodo calcular dele deveria me trazer um tipo Scalar Why do you think that? If Arg is Expression Arg is Expression.

  • My method of calculating() in Expression<R> returns R, so I believe that calculating in an Expression<Scalar> would return Scalar, not?

  • You in the case just have 1/arg.calcular().getValor() at the place where it is written Parametro?

  • That, 1/arg.calcular().getValor() in place of parameter, but as arg.calcular() is Expression, it has no method getValor(). And the return is even Scalar, I edited there in the question.

1 answer

5


You are inheriting without specifying 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 this case R extends Expression, thus the basic type of R will be Expression, if there were no upper bound explicit the type would be Object).


Point solution:

Do Scalar be a Expression<Scalar> (in that case calcular will return a Scalar).

class Scalar extends Expression<Scalar> 

Do InversãoScalar define at least the type Expression<Scalar> for T (arg will be that kind T), and some kind of Expression for R that isn’t even being used:

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

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

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

P.S.: your solution is a bit loaded with generics and inheritance (the possibilities of combinations there make the use of the API complicated; even if you want to go this way you will have to rethink your Bounds and what should be parameterizable). I recommend reading this question: "It is wrong to use class inheritance to group common behaviors and attributes?", as well as in the code of other libraries dealing with mathematical expressions in Java.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.