Generic and Comparable in Java

I have a question that I cannot see answered, If anyone can give me a plausible explanation I will be grateful.

Assuming I have 2 classes:

public class Figura implements Comparable<Figura>
{
    private final int largura, altura;

    Figura(int l, int a)
    {
        largura = l;
        altura = a;
    }

    @Override
    public int compareTo(Figura o) 
    {
        if((o.largura*o.altura) > (this.altura * this.largura))
            return 0;
        else
            return 1;
    }


}


public class Rectangulo extends Figura 
{
    Rectangulo(int altura, int largura)
    {
        super(altura, largura);
    }


}

When I try to create a generic method that allows comparing 2 elements, if I do:

 public static <T> int comparaRect(T rect, Comparable<? super T>  outroRect)
 {
     return outroRect.compareTo(rect);
 }

Works without problem. But if you do:

  public static <T> int comparaRect(T rect, Comparable<? super T>  outroRect)
     {
         return rect.compareTo(outroRect);
     }

No longer works. Getting the error of cannot find symbol T etc.

My question here is: why can I only do one way and not both, since one element is inherited from the other and soon also inherits the interface comparable figure?

Thank you right now.

Author: Miguel Ruivo, 2017-11-04

1 answers

My question here is: why can I only do one way and not both, since one element is inherited from the other and then also inherits the comparable figure interface?

The Problem Has No relation to inheritance, the problem is in the form that the method was mounted:

public static <T> int comparaRect(T rect, Comparable<? super T>  outroRect) {
   return rect.compareTo(outroRect);
 }

This way the compiler cannot guarantee (in a secure way) that T is an instance that implements / contains the method compareTo , the method accepts any object like T rect.

If you want to perform the operation with both arguments, the method must be Moting in a different way:

public static <T extends Comparable<T>> int comparaRect(T rect, T outroRect) {
   return outroRect.compareTo(rect);
}

Or:

public static <T extends Comparable<T>> int comparaRect(T rect, T outroRect) {
   return rect.compareTo(outroRect);
}

This way you ensure that the two arguments T implement the interface Comparable.

 2
Author: Tom Melo, 2017-11-05 13:05:58