2016-05-13 15 views
2

ich die folgenden Einrichtungen in meinem Domain-Modell hat:Java generische obere begrenzt Wildcard Fehler

class Point { 
    public String details; 

    public Point() { 
     details = "empty"; 
    } 

    public Point(String details) { 
     this.details = details; 
    } 
} 

class BasicPoint<X, Y> extends Point { 
    public X x; 
    public Y y; 

    public BasicPoint() {} 

    public BasicPoint(X x, Y y) { 
     this.x = x; 
     this.y = y; 
    } 
} 

class Collector<T> { 
    T elem; 

    public void collect(T elem) { 
     this.elem = elem; 
    } 
} 

Ich mag Operationen auf Daten anzuwenden und diese Daten als Punkt oder BasicPoint zurückkehren, wie oben erklärt, aber der Compiler mit dem folgenden Fehler beschweren obwohl OUT erstreckt Point:

class Operator<OUT extends Point> { 
    public Collector<OUT> operate(Collector<OUT> collector) { 

     // compile error, collect(OUT) cannot be applied to BasicPoint<Integer, Integer> 
     collector.collect(new BasicPoint<Integer, Integer>(1,2)); 

     return collector; 
    } 
} 

Main-Methode sollte wie folgt aussehen:

Collector<BasicPoint<Integer, Integer>> c = new Collector<>(); 
c = new Operator<BasicPoint<Integer, Integer>>().operate(c); 
System.out.println(c.elem.getClass() == new BasicPoint<Integer, Integer>().getClass()); 
+0

haben Sie den Code, öffnen Sie eine IDE und generieren Sie die Ausgabe. – user1933888

+0

Das Problem ist, dass der Code nicht kompiliert, es zeigt einen Fehler in der Operator-Klasse in der Frage definiert – zequihg50

+0

Was ist der Compiler-Fehler dann? –

Antwort

2

Ihre Operator ist generische es kann nicht collect auf eine BasicPoint, nur OUT gelten.

abstract class Operator<OUT extends Point> { 
    abstract Collector <OUT> operate(Collector<OUT> collector); 
} 

Und ein BasicPointOperator enthält dann die tatsächliche Implementierung, die Sie wollen: Sie können Ihre Collector abstrakt machen

class BasicPointOperator extends Operator<BasicPoint<Integer, Integer>> { 

    @Override 
    Collector<BasicPoint<Integer, Integer>> operate(Collector<BasicPoint<Integer, Integer>> collector) { 
     collector.collect(new BasicPoint<Integer, Integer>(1,2)); 
     return collector; 
    } 
} 

oder PointOperator, die ein bisschen mehr Generika ist

class PointOperator extends Operator<Point> { 

    @Override 
    Collector<Point> operate(Collector<Point> collector) { 
     collector.collect(new BasicPoint<Integer, Integer>(1,2)); 
     return collector; 
    } 
} 
+0

Afaik es _could_ arbeiten die Art, wie er es in erster Linie programmiert, weißt du _why_ es dosent Arbeit? Ich denke, der Compiler ignoriert einfach den Typ von 'OUT' innerhalb von 'Operator'. – hinneLinks

+1

Es funktioniert nicht, da 'BasicPoint' nicht vom Typ' OUT' ist. Sie haben nur einen gemeinsamen Vorfahren "Point". –

1

Das Problem ist, dass Sie die Dinge in nicht setzen können, wenn der Typ Parameter ist contravariant. Etwas wie das

public Collector<?> operate(Collector<? super Point> collector) { 
    collector.collect(new BasicPoint<Integer, Integer>(1,2)); 
    collector.collect(new Point()); 

    return collector; 
}