2009-06-01 5 views
1

Ich habe ein kleines Problem, das die Java-Sprache verstehtJava: Ableitung aus einer generischen Liste/Sammlung

public class PhonebookEntryList extends List<PhonebookEntry> 
{ 
    public PhonebookEntryList(String filename) throws IOException 
    { 
     //loadListFromFilename(filename); 
    } 

    public void saveListToFilename(String filename) throws IOException 
    { 
     //Do something to save it to a file 
    } 
} 

Ich kann das nicht tun, weil Liste ein generischer Typ ist (natürlich). Ich weiß, was das bedeutet, aber im Moment kann ich mir keine Lösung für dieses Problem vorstellen.

Können Sie mir helfen, es zu lösen? Danke!

Antwort

3

Nein, Ihr einziges Problem ist, dass Sie extend ing ein interface sind; Sie müssen stattdessen implement es.

public class PhonebookEntryList implements List<PhonebookEntry> 

sollte funktionieren; oder Sie könnten es vorziehen, eine konkrete Klasse zu erweitern:

public class PhonebookEntryList extends ArrayList<PhonebookEntry> 

oder

public class PhonebookEntryList extends LinkedList<PhonebookEntry> 
+0

Sie liegen falsch, zu; Er hat mindestens zwei Probleme mit diesem Code. Ich würde drei sagen. – alamar

+1

Wirklich? Direkt daneben sehe ich nichts anderes (vorausgesetzt, er hat seinen eigentlichen Code im Konstruktor und in der Methode einfach weggelassen). –

+2

Er sollte eine Liste nicht erweitern, wenn er sein Listy-Verhalten nicht ändern möchte; Es ist eine riesige WTF, integrierte Sammlungen zu erweitern, um Ihre Daten POJOs zu machen. Das ist sein Hauptproblem: sein Design ist Mist, ich denke er überschätzt auch OO wie in "riesigen Klassenhierarchien". – alamar

0

List<T> ist eine Schnittstelle, keine Klasse, so kann man daraus nicht erben. Sie können jedoch von einem generischen Typ erben, der das Argument type liefert, wenn Sie z. eine Sammlung für einen bestimmten Typ mit einem Verhalten, das nur für diesen Typ spezifisch ist.

3

Das geht nicht, weil List eine Schnittstelle ist. Aber! Sie sollten eine List-Klasse nicht erweitern oder implementieren, um eine PhonebookEntryList zu erstellen. Dies ist ein Konstruktionsfehler.

Sie tun sollten:

public class PhonebookEntryList 
{ 
    private List<PhonebookEntry> entries; 

    public PhonebookEntryList(String filename) throws IOException 
    { 
     //loadListFromFilename(filename); 
    } 

    public void saveListToFilename(String filename) throws IOException 
    { 
     //Do something to save it to a file 
    } 
} 

D.h. Ihre PhonebookEntryList sollte eine Liste enthalten, anstatt sie zu erben.

+2

Ich bin nicht glücklich mit dieser Lösung, weil ich die 'eingebettete Liste' von außerhalb der Klasse nicht verwenden kann (Hinzufügen, Entfernen, Finden, ...) –

+0

classic is-a vs. hat-eine Beziehung. –

+1

können Sie die "eingebettete Liste" von außerhalb der Klasse verwenden. Fügen Sie einfach Ihre eigenen add(), remove(), find() Methoden zu Ihrem Telefonbuch hinzu. Dann hätten diese Methoden die entsprechenden Methoden add(), remove(), find() Ihrer privaten Liste aufgerufen. –

0

Wenn Sie sich die JavaDoc for List ansehen, sehen Sie (wie andere bereits erwähnt haben), dass es sich um eine Schnittstelle handelt, nicht um eine Klasse. Was Sie am ehesten tun möchten, ist auf der gleichen JavaDoc-Seite unter "Alle bekannten implementierenden Klassen" zu sehen, und Sie sehen AbstractList. Erweitern Sie dies. Alternativ erweitern Sie eine der nicht abstrakten List Implementierungen.

Hinweis: Wenn jemand anfängt, eine der Java Collection-Klassen zu erweitern, gehen Sie meistens die falsche Route ein. Normalerweise ist es besser, eine der vorhandenen Sammlungen in Ihrer Klasse zu verwenden und alle Anforderungen im Zusammenhang mit Sammlungen zu übernehmen, die Sie benötigen. Oder geben eine unveränderbare Proxy Ihrer Sammlung:

public class MyClass { 
    private final List<PhonebookEntry> myList = new LinkedList<PhonebookEntry>(); 

    public List<PhonebookEntry> getList() { 
    return Collections.unmodifiableList(myList); 
    } 
} 

Normalerweise ist es am besten, eine Klasse zu erweitern, nur wenn Sie beabsichtigen, ein anderes Verhalten zu haben, als die Klasse, die Sie erstrecken. Die Vererbung ist spröder als die Zusammensetzung.

+0

Bitte exportieren Sie keine Iteratoren; Es spielt nicht gut mit Java 5 und seinem "Smart for". – alamar

+0

Und Sie möchten nicht, dass es Iterable implementiert, aus demselben Grund, aus dem Sie nicht wollen, dass List implementiert wird. Besser machen Sie es öffentliche Liste entries() {return Collections.unmodiableList (Einträge); } – alamar

+0

Angemessene Punkte, beides. Ich habe mein Codebeispiel aktualisiert. – Eddie

0

List<T> ist eine Schnittstelle.

Wenn Sie extend eine Klasse möchten, müssen Sie eine Implementierung (ArrayList<T> vielleicht) wählen müssen: extends ArrayList<PhonebookEntry>

Wenn Sie einen List ändern Sie den Code implementieren möchten: implements List<PhonebookEntry>

+0

Kann die Person, die mich unten gewählt hat, erklären warum? –

+0

Jemand ist anscheinend sehr wütend. –

0

Ihr Problem ist, dass Sie versuchen, eine Schnittstelle zu erweitern, anstatt sie zu implementieren.

Zusammensetzung ist was du willst. Erstellen Sie eine Klasse, die eine Liste umbricht (oder etwas, das diese Schnittstelle kopiert)

und fügen Sie Funktionalität hinzu.

0

Sollte ich erwähnen, dass List eine Schnittstelle und keine Klasse ist? Nein. Ich denke, du hast es verstanden.

Ich möchte jedoch darauf hinweisen, dass es normalerweise besser ist, den Persistenzmechanismus nicht in die Listenklasse einzubetten. Es gibt dieses Ding namens Besuchermuster, das besser funktioniert. Indem der tatsächliche Persistenz-Code in einer separaten Klasse platziert wird, wird die gesamte logische Komplexität der App reduziert (auf Kosten einer zusätzlichen Klasse), und Ihr Telefonbuch wird für Orte mit Abhängigkeiten vom Persistenz-Mechanismus freigegeben, die gut aussahen Als du den Code zum ersten Mal entworfen hast, siehst du nicht mehr so ​​gut aus. Zum Beispiel, wenn Sie möchten, dass das Telefonbuch ein Element in einer ORM-referenzierten Datenbank ist.

+0

Rate mal was? Er braucht diese Klasse nicht, wenn er das persistente Material spaltet! – alamar