2012-11-07 5 views
8

Ich habe eine Designfrage. Im Folgenden finden Sie Timestamp-SchnittstelleGutes Design in Generics

/** 
* <T> Type of Timestamp. For ex: Date, long, Calendar etc 
* 
*/ 
public interface TimeStamp<T> extends Comparable<TimeStamp<T>> 
{ 

    /** 
    * Returns the timestamp. 
    * @return 
    */ 
    public T getTimeStamp(); 

} 

ich im Grunde eine List Klasse haben wollen, die nur Timestamps enthalten. Das Hinzufügen von Elementen auf der Liste hängt im Wesentlichen vom Zeitstempel ab. Wie sollte meine List-Klasse-Deklaration sein?

Wenn ich für Komposition entscheiden, wird der Code wie folgt aussehen:

public class TimeList<T> implements List<TimeStamp<T>> 
{  
    private List<TimeStamp<?>> list = new ArrayList<TimeStamp<?>>(); 
    //other list methods who will return based on list above 
    ..... 
} 

Aber die oben ist nicht sinnvoll. Zum Beispiel, wenn ich eine Klasse DefaultTimeStamp implments TimeStamp<Long> und instanziiert TimeList als

TimeList<DefaultTimeStamp> l = new TimeList<DefaultTimeStamp>(); 

Dann Anycall zu l.add(elem) ein TimeStamp<DefaultTimeStamp> erwarten, die falsch ist.

Eine Erklärung: public class TimeList<TimeStamp<T>> implements List<TimeStamp<T>> würde

Zeitfehler geben kompilieren Was die Erklärung meines TimeList<Type> sein sollte? Letztlich ist es nur eine Liste nur Timestamps

+0

Da Liste nichts Hinzufügen auf seine Zeitmarke abhängen . – Jatin

+1

soll TimeList TimeStamp für bestimmte T von für irgendein T enthalten? –

+0

Ja. Das ist für Berechnungen erforderlich – Jatin

Antwort

2

enthält, die ich nicht verstehe, warum Sie

TimeList<DefaultTimeStamp> l = new TimeList<DefaultTimeStamp>(); 

tun wollen Wenn Sie jede Art von TimeStamp<Long> hinzufügen zu können, wollen. Der obige Weg würde Benutzer dazu zwingen, DefaultTimeStamp zu verwenden, wenn Sie einige implementationsspezifische Gründe dafür hätten ... aber normalerweise nicht, offensichtlich.

TimeList<TimeStamp<Long>> l = new TimeList<TimeStamp<Long>>(); 
DefaultTimeStamp dts = new DefaultTimeStamp(System.currentTimeMillis()); 
l.add(dts); 

Sollte gut funktionieren!

+0

Das genau wollte ich nicht. ich meine - TimeList l = neue TimeList (); – Jatin

+1

Ich weiß, dass Sie das nicht tun wollen, tun Sie die untere Sache :) – durron597

0

Die Klasse TimeList muss nicht generisch sein. Sie einfach könnte den TimeList wie erklären:

public class TimeList implements List<Timestamp> { 

private List<Timestamp> list = new ArrayList<Timestamp>(); 

und dann verwenden,

TimeList l = new TimeList(); 

    l.add(new DefaultTimestamp1()); 
    l.add(new DefaultTimestamp2()); 

Es funktioniert perfekt. Sie können nur Objekte hinzufügen, die die Schnittstelle Timestamp erweitern.

+0

Dies ist die andere Lösung.+1 – durron597

+1

Aber das würde mehrere Kompilierzeitwarnungen geben. – Jatin

+0

Ich hatte keine Warnungen, können Sie die Warnungen zeigen, die Sie erhalten und sagen, welche jdk benutzen Sie? – remigio

0
public class TimeList<T> extends ArrayList<TimeStamp<T>>{ 
} 

Das ist es.

+0

Wenn seine List-Methoden nur basierend auf seiner 'privaten' Variablen zurückgeben, dann ist dies ein guter Weg. Durch das Implementieren der "List" -Schnittstelle versteckt er jedoch Methoden, die in 'ArrayList' und nicht in der' List'-Schnittstelle existieren. (Wie 'sureCapacity'). –

0

Obwohl ähnlich in Java wiederholt werden, in scala man es durch tun können:

trait TimeStamp[T <: Comparable[T]] extends Comparable[TimeStamp[T]] 
{ 
def getTimeStamp:T; 
def compareTo(to:TimeStamp[T]) =this.getTimeStamp.compareTo(to.getTimeStamp) 
} 

Und TimeList Erklärung ist wie folgt:

class TimeList[T <: TimeStamp[_]] extends ArrayList[T] 
+0

Wer hat etwas über Scala gesagt? –

Verwandte Themen