Generische Containerklasse

Loppi

Mitglied
Hallo,
ich habe gerade ein ganz einfaches Problem (denke ich jedenfalls mal).
Und zwar habe ich folgende drei Klassen: Mensch(String name), Tier(String name), Container.
Die Container-Klasse hat eine ArrayList, in der beliebig viele Menschen und Tiere sein können und sie soll eine Methode haben, die nach Benutzereingabe abgleicht, ob ein Mensch/Tier mit dem eingegebenen Namen in der ArrayList ist.

An sich hört sich das ganz einfach an, aber mein Problem ist jetzt, dass ich es nicht schaffe, die ArrayList so zu definieren, dass ich noch auf die getter-Methoden von Mensch und Tier zugreifen kann.

Das hier ist erstmal meine Containerklasse:

Code:
public class Container<T>
{
   ArrayList<T> meineLeute = new ArrayList();
   
   public void insertTyp(T einTyp)
   {   
      meineLeute.add(einTyp);
   }
}

Wenn ich jetzt z.b. das hier schreibe:
Code:
String test = meineLeute.get(0).getName()
kommt natürlich, dass die Methode getName() nicht gefunden werden kann, da der Typ T nunmal keine solche Methode hat.

Wie also definiere ich diese ArrayList so, dass ich auf die getter-Methoden von Mensch und Tier zugreifen kann (ohne eine Oberklasse "Lebewesen" zu machen, um die ArrayList durch den Typ zu definieren)?
 
Du kannst (solltest zumindest) nicht einfach zwei verschiedene Klassen in eine Collection packen. Gerade bei Klassen wie Mensch und Tier bietet sich doch eine Oberklasse Lebewesen an, die gewisse Funktionalitäten (getName() z.b) generalisieren kann, und von der Mensch und Tier erbt. Dann kannst du dir eine ArrayList<Lebewesen> bauen.
Wenn du jetzt alle Lebewesen in deiner ArrayList auf Namen vergleichen willst schreibst du:
Java:
public boolean checkListForName(ArrayList<Lebewesen list, String name)
{
for(Lebewesen l: list)
{
if(l.getName().equals(name))
{return true;}
}
return false;
}
 
Wie also definiere ich diese ArrayList so, dass ich auf die getter-Methoden von Mensch und Tier zugreifen kann (ohne eine Oberklasse "Lebewesen" zu machen, um die ArrayList durch den Typ zu definieren)?
Du musst bei der Definition der Liste einen Typen angeben, der Dir die gewünschten Getter (also z.B. getName) als Methoden zur Verfügung stellt. Wenn Du keine gemeinsame Oberklasse "Lebewesen" definieren willst, dann tut es auch ein Interface (z.B. "Named"), das die Methode getName definiert und das die Klassen Tier und Mensch implementieren. Das greift nicht so stark in die Klassenhirarchie ein, wie eine Oberklase.
[Java]
public interface Named {
public String getName();
}

public class Tier implements Named {...}
public class Mensch implements Named {...}

// und dann im Code

// Das stand vorher drinen. Ist natürich Quatsch! Dank an bygones!
// List<? extends Named> namedBeings = new ArrayList<? extends Named>;

//Korrigierte Version nach bygones' Hinweis.
List<Named> namedBeings = new ArrayList<Named>();
...
[/Java]
Wenn Du auch das nicht willst. Dann lautet die Antwort auf Deine Frage: Geht nicht. Eine typsichere Liste mit gemischten Typen ist nicht möglich. Hier kannst Du dann nur wie früher mit einer ungetypten Liste arbeiten und die Elemente casten.
 
Zuletzt bearbeitet von einem Moderator:
oder man überschreibt equals und benutzt List#contains
dass funktioniert aber nicht in seinem beispiel, da er einen String hat und damit ein Lebewesen sucht., equals ueberschreiben und contains nutzen geht nur bei gleichen Typen.

@nillehammer:
deine idee ist nett, funktioniert aber leider gar nicht.

Zum einen kannst du keine [c]new ArrayList<? extends Named>[/c] schreiben, sondern es muss [c]new ArrayList<Named>()[/c] sein.
Weiterhin kannst du bei List<? extends Named> list, kein add nutzen, da der compiler dir nicht erlaubt eine unterklasse hinzufuegen

Lass das ? extends weg und dann gehts
 
dass funktioniert aber nicht in seinem beispiel, da er einen String hat und damit ein Lebewesen sucht., equals ueberschreiben und contains nutzen geht nur bei gleichen Typen.

jo hast du recht, hatte es ehrlich gesagt nur überflogen. wobei man nen string auch auf die schnelle in ein lebewesen gewrappt bekommt. frage ist dann nur, ob die equals dann nicht zu ungenau ist
 
bygones hat gesagt.:
@nillehammer:
deine idee ist nett, funktioniert aber leider gar nicht.
...
Lass das ? extends weg und dann gehts
Jo, hast natürlich Recht. Das war vollkommener Blösinn. Habe den Code freihändig getippt. Deswegen ist es mir nicht aufgefallen. Habe es jetzt korrigiert (natürlich mit Hinweis auf Dein Urheberrecht 😉 ).
 
Zuletzt bearbeitet von einem Moderator:
Vielen Dank für die Antworten.
Habe beides probiert und das mit der Schnittstelle finde ich ein wenig eleganter, da ich eben, wie bereits gesagt wurde, damit nicht so wirklich an der Klassenhierachie rumfusche, was ich ja nicht möchte.

Die Oberklasse "Lebewesen" wollte ich übrigens nur nicht, weil in der Aufgabenstellung nur die beiden Unterklassen erwähnt werden. 🙂
 
Loppi hat gesagt.:
Die Oberklasse "Lebewesen" wollte ich übrigens nur nicht, weil in der Aufgabenstellung nur die beiden Unterklassen erwähnt werden.
Ich könnt wetten, dass sie nur deswegen nicht erwähnt wude, weil Dein Prof. wollte, dass Ihr selbst auf diese Möglichkeit kommt. Mit der interface Lösung und Deiner Erklärung dazu solltest Du ihn um so mehr beeindrucken🙂.
 
Ich könnt wetten, dass sie nur deswegen nicht erwähnt wude, weil Dein Prof. wollte, dass Ihr selbst auf diese Möglichkeit kommt. Mit der interface Lösung und Deiner Erklärung dazu solltest Du ihn um so mehr beeindrucken🙂.

Die Lösung habe ich sogar direkt anfangs realisiert, weil ich eben keine Möglichkeit gesehen habe, das anders zu lösen.
Ich denke aber, ich werde da gar keinen beeindrucken, da es nur um Klausurvorbereitung geht. 🙂
 

Zurück
Oben