Lösung für Problem mit dem Vector



  • Hallo.

    Also, ich habe irgendein Programm geschrieben, welches mit einem Vector zur Laufzeit viele verschiedene Objekte verarbeitet. Diese sind eben von verschiedenen Klassen. Und wenn ich nun per <Vector>.get(int) ein Objekt aufraufe, werden keinerlei Methoden oder Variablen der Klasse erkannt. Was wie ich vermute, daran liegt, dass der Rückgabewert der Methode get(int) Object ist. Aber da der Algorithmus flexibel sein soll, also jede meiner Klassen bearbeiten können soll, ist das mit dem Casten, für meine Begriffe nicht drin. Also, wie kann ich das verwirklichen?
    Natürlich habe ich mir auch selbst Gedanken darüber gemacht, welche aber in endlose
    Zeilen von if-else-Schleiden ausarten würden. Und deshalb hoffe ich, dass jemand eine gute Lösung weis.

    Danke!



  • Du sprichst mit deinem Problem ein Thema an, welche sich eingefleischte C++-Fans auf die Flagge zum Feldzug gegen Java geschrieben haben - typsicherheit in Containern bzw. das Fehlen eines Template-Mechanismus in Java. Derzeit kommst Du um das Abfragen und Casten auf den jeweiligen Typ nicht rum. Es gibt zwar einen Weg aber ob der für dein Problem passt musst du selbst eintscheiden. Also folgendes wären die Optionen:

    1. Abfrage via instanceof mit anschließendem Cast: [java]Vector v = new Vector(0, 1);
      ...
      Object obj = v.get(0);
      MyOwnClass myOwnClassObject = null;
      if (obj instanceof MyOwnClass)
      myOwnClassObject = (MyOwnClass)obj;
      else ...[/code]
      Die zweite Methode wäre sich zu überlegen ob es die benötigten Methoden, in allen Objekten innerhalb des Vectors gibt. Wenn ja dann ließe sich eine Schnittstelle (Interface) mit genau diesen Methodenköpfen basteln und jede einzelne Klasse könnte dieses Interface implementieren. Damit wärst Du dann in allen Fällen (gesetzen Falls du legst nur solche Objekte ab) auf der sicheren Seite.


  • Hallo Cengiz,

    hat nicht funktioniert. Danke trotzdem.

    Danke!



  • Was soll nicht funktioniert haben? Sei doch mal "a weng" präziser ...



  • Hallo.

    Ich hatte mich irgendwie ein bisschen falsch ausgedrückt. Das ganze hat doch funktioniert. Aber weißt du Cengiz, ich habe irgendwie die Lust an Java verloren, weil das so unheimlich kompliziert ist. Ich werde mein Spiel jetzt erstmal in C++ umsetzen und wenn Java 1.5 mit Generics raus ist, werde ich mein Glück nochmal versuchen. 🙄

    Danke.



  • Wie du meinst obwohl ich nicht sehe was daran nun kompliziert sein soll. Wenn deine Applikation nur wegen dem fehlen von Templates nicht beendet wird, dann ist das eher kein gültiges Argument 😉



  • Hey, also was dieser "andere Pogo" geschr. hat stimmt zwar, also dass es nicht geklappt hat(zumindest im 1. post), aber trtozdem werd eich das ganze nicht in c++ schreiben!

    Also, es hat wirklich nich geklappt. Leider.

    Also ich habe ein Interface geschr. und alle Klassen im Vector implementieren dieses. Aber trotzdem klappt es nicht. Habe ich es vielleicht falsch umgesetzt? Könntest du mir bitt ein kurzes Bsp. schreiben CengizS? 🙄



  • Wann ist es denn endlich soweit, dass nur registrierte Benutzer Beiträge erstellen können?

    Datei: RealPogo.java
    ----------------------

    interface RealPogo {
        void DeineMethode();
    }
    

    // Datei: Pogo.java
    // ----------------------

    import java.util.Vector;
    
    class Pogo implements RealPogo {
    
      private int number;
    
      public Pogo(int number) {
        this.number = number;
      }
    
      public void DeineMethode() {
        System.out.println("Ser's Pogo, " + number );
      }
    
      public static void main(String args[]) {
        Vector v = new Vector();   
        for (int i=0; i<5; i++) {
          v.add(new Pogo(i));
        }      
    
        Pogo x = null;   
        for (int i=0; i<v.size(); i++) {
          ((RealPogo)v.get(i)).DeineMethode();
        }
      }   
    }
    

    [ Dieser Beitrag wurde am 31.12.2002 um 16:41 Uhr von ms editiert. ]



  • Klar! Here we go...[java]interface <InterfaceName> {
    // Hier deine Methodenköpfe...
    public String getString();
    ...
    public void validateData();
    }

    class A implements <InterfaceName>
    {
    // Hier alle Methoden aus dem Interface implementieren ...
    public String getString() {
    ...
    }
    ...
    public void validateData() {
    ...
    }
    }

    class B implements <InterfaceName>
    {
    // Hier alle Methoden aus dem Interface implementieren ...
    public String getString() {
    ...
    }
    ...
    public void validateData() {
    ...
    }
    }

    class C implements <InterfaceName>
    {
    // Hier alle Methoden aus dem Interface implementieren ...
    public String getString() {
    ...
    }
    ...
    public void validateData() {
    ...
    }
    }[/code] etc. pp.

    Dann musst du in deiner if-Anweisung nur noch prüfen ob das Object instanceof <InterfaceName> ist und fertig.



  • Mhh, das kapiere ich jetzt immer noch nicht ganz. Also, ich dachte, wenn das Interface implementiert ist, das dann die Methoden gleich bekannt sind. Aber naja.
    Also das mit dem instanceof. Also muss ich das so machen, dass ich dann in das Interface caste? Also egal welche Klasse ich vom Vector haben will, sobald sie das Interface implementiert, brauche ich sie nur noch in den Interfacetypen casten da das Interface den Datentyp der Klasse verändert? Habe ich das richtig verstanden? 🙂



  • Yep!



  • *TRÄLLA* 🙄



  • Sehr gut, Danke CengizS!

    Das zumindest, klappt jetzt! 🙂
    Noch eine Frage: Ich habe mal meine run-Methode getestet, weil ich irgendwie Probleme mit dem repainten habe, also meine Objekte werden nicht neugezeichnet, das irgendwas mit der Veränderung der Koordinaten nicht klappt, aber eine andere Sache, die mir dabei auffiel.

    Ist es normal, dass nur bei jedem 8. Durchlauf der run-Methode repaint aufgerufen wird? Doch eher nicht, oder? 🙄

    [ Dieser Beitrag wurde am 02.01.2003 um 01:01 Uhr von Pogo editiert. ]


  • Mod

    Original erstellt von Pogo:
    **
    Ist es normal, dass nur bei jedem 8. Durchlauf der run-Methode repaint aufgerufen wird? Doch eher nicht, oder? 🙄
    **

    Könnte schon normal sein! ...am Besten, du zeigst das mal her. Wenn du etwas bei jedem Durchlauf der der run-Methode neu zeichnen möchtest, dann kannst du mal folgendes ausprobieren:
    [java]
    etwas.paint(etwas.createGraphics());[/code]
    ...sag mal Bescheid, ob das klappt. Das interessiert mich auch.

    EDIT : Warum das normal sein könnte :

    AFAIK ist es so, dass die GUI einen extra-Thread besitzt. Wenn du repaint aufrufst, dann wird nicht automatisch sofort neu gezeichnet, sondern der andere Thread bekommt eine Nachricht in irgendeinen Behälter (ne LinkedList oder so). Diese Nachricht wird erst dann bearbeitet, wenn der GUI-Thread wieder dran ist. Es kann aber sein, dass die Schleife in deiner run-Methode mehrmals durchlaufen wird, bevor der GUI-Thread wieder dran ist. ...dann müßte die Nachricht an den GUI-Thread eigentlich mehrmals in dem Behälter gespeichert werden, ich denke aber, dass mehrfache Nachrichten einfach ignoriert bzw. gelöscht werden.

    (Das war jetzt zu mindestens 50% geraten! :))

    [ Dieser Beitrag wurde am 02.01.2003 um 06:53 Uhr von Gregor editiert. ]



  • Mhh, also ich werde es mal versuchen. Mhh, ic habe wohl vergessen, unter welchen Umständen die paint-methode nur jedes 8. Mal aufgerufen wird, aber du hast es ja trtozdem verstanden Gregor. 🙂

    Also, so sieht meine run-Methode aus:

    public void run() {
    while(runner != null) {
    try {
    Thread.sleep(500);
    } catch (InterruptedException e) { }
    System.out.print(x+"//"+y+" ");
    x += rx;
    y += ry;
    repaint();
    }
    }

    Naja, also mit print, habe ich eben die ganze Sache mal überprüft, und das ganze natürlich ein bisschen verlangsamt, da ich sonst nicht wirklich mitgekommen wäre(Ich habe über DOS-Ausgabe noch etliche andere Werte überprüft, weil da bei meinem Prog. so einiges nicht klappt... 😃 ).

    So, zu deinem Vorschlag, wie genau meinst du das?

    So in der Art: "this.paint(this.createGraphics());" ?

    Also, die run-Methode soll in meinem Fall, ihren eigenen Inhaber neuzeichnen.


  • Mod

    ersetze "repaint ();" durch

    paint (getGraphics());

    ...createGraphics scheint es nicht überall zu geben.



  • Ok, das mit dem createGraphics hat auch nicht geklappt, also, könnte ich das mal versuchen. So, jetzt ist mir aber ganz entgangen, wieso. Denn jetzt klappt mein Prog, gut, es wird immer nur noch bei ca. jedem 8. Durchlauf neugezeichnet, aber wenigtens klappt es. Vorher hats nicht geklappt, und ich habe keine Ahnung warum. Also es soll ja immer ein bewegl. Objekt gez. werden, also habe ich die x und y Koordinaten in der run-Methode verändern wollen. Aber das hat nicht geklappt, also habe ich den gleichen code in die paint-Methode geschr. und jetzt klappt´s...

    Ok, aber ich werde das mal probieren, vielleicht wird ja dann wirklich bei JEDEM Durchlauf neugezeichnet.



  • Wenn ihr wollt dass das Objekt wirklich immer neu gezeichnet wird müsst ihr invalidate() auf das Objekt aufrufen mit anschließendem validate(). Damit sollte die Komponente dazu gezwungen werden sich neu zu zeichnen.



  • Danke CengizS!

    Damit könnte ich nämlich meine nächste Frage lösen. Denn wenn ich so Sachen zeichne, sieht das immer ziemlich Ruckartig aus. Wenn ich aber bei jedem Durchlauf die Koordinaten einfach um eins erhöhe und die Komponente zum repaint gezwungen wird, dann sieht das doch bestimmt schon viel flüssiger aus. 🙂


Anmelden zum Antworten