Was ist das fuer ein Konstrukt?

  • Hallo,


    ich wuerde gerne wissen was das fuer eine merkwuerdige Konstruktion ist, die haeufig bei eventhandlern auftritt.


    Java
    alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        				 public void onClick(DialogInterface dialog, int which) {
          				 Toast.makeText(getActivity().getApplicationContext(), "You clicked on OK", Toast.LENGTH_SHORT).show();
          				 }
      				 });


    alertDialog ist das Obkjekt. setPositiveButton ist eine Methode von alertDialog. Dann folgen die beiden Parameter "Ok" und new DialogInterface.OnClickListener(). Was ich nicht verstehe ist, dass an den zweiten Parameter eine Anweisung angehaengt wird, die ebenfalls eine Methode definiert.


    Wieso kann man den Anweisungsblock einfach dort einfuegen? Wie haengt der Anweisungsblock zusammen mit dem Rest? Gibt es vielleicht einen aequivalenten Ausdruck fuer das Konstrukt, so dass ich verstehe was es eigentlich macht?


    Gutelo

  • Inzwischen habe ich herausgefunden, dass DialogInterface.OnClickListener()


    ein Interface ist. Deshalb nehme ich an, dass


    public void onClick(DialogInterface dialog, int which);


    eine Methode aus diesem Interface ist, die nun implementiert wird. Aber dass man das einfach so hinter den Parameter schreibt ist mir immer noch nicht klar.

  • In Java kannst Du bequem Inline Funktionen und anonyme Inline Klassen erstellen.

    Java
    class MyClass {
      void method() {
        alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int which) {
          	Toast.makeText(getActivity().getApplicationContext(), "You clicked on OK", Toast.LENGTH_SHORT).show();
          }
        });
      }
    }


    ist ungefähr dasselbe wie

    Java
    class MyClass implements DialogInterface.OnClickListener() {
      void method() {
        alertDialog.setPositiveButton("OK", this);
      }
      public void onClick(DialogInterface dialog, int which) {
        Toast.makeText(getActivity().getApplicationContext(), "You clicked on OK", Toast.LENGTH_SHORT).show();
      }
    }


    und auch das gleiche wie

    Java
    class MyListener implements DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int which) {
        Toast.makeText(getActivity().getApplicationContext(), "You clicked on OK", Toast.LENGTH_SHORT).show();
      }
    }
    class MyClass {
      void method() {
        alertDialog.setPositiveButton("OK", new MyListener());
      }
    }


    Du hast für die Implementierung solcher Interfaces immer diese drei Möglichkeiten.

    • Ist nur eine Kleinigkeit, die für jedes 'onClick' anders ist. Mach es als anonyme innere Klasse.
    • Ist ne Menge an Aufwand, die für jedes 'onClick' gleich ist. Implementiere das Interface in der aufrufenden Klasse.
    • Ist ne Menge an Aufwand, die für jedes 'onClick' unterschiedlich ist. Implementiere das Interface in je eine eigene Klasse.

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Nö das stimmt nicht.
    Wenn die Klasse eine Aufgabe erfüllt und dafür diese Informationen gebraucht werden, dann müssen die Daten eh da sein um diese Klasse zu nutzen. Wenn ich das ganze nun entkoppel, kann ich die Klasse zwar immer und überall verwenden, sie kann ihre eigentliche Aufgabe aber nur erfüllen wenn die Informationen per setter gesetzt sind. Nun fragt sich, möchte ich die Klasse immer verwenden können und händisch die Informationen per setter reingeben was zu Fehlern führen könnte, oder möchte ich mich vor Programmierfehlern schützen und diese bereits im Konstruktur setzen.


    Natürlich sieht das schon wieder anders aus wenn zum Zeitpunkt der Instanziierung die Informationen noch nicht zur Verfügung stehen (das solls ja auch geben :P), dann muss man halt mit settern arbeiten.

  • Ganz korrekt wäre es mit dem Target-Action-Paradigma.
    Ich klicke drauf, und dann wird auf dem Target 'Activity' die Action 'ButtonPressed' ausgeführt.
    So wie es der OnClick-Eintrag im XML UI macht.


    Die Abhängigkeit ein Objekt an die Methode zu übergeben ist meiner Meinung nach totaler Bullshit.


    Ich benötige da ja eine Funktion, die irgend etwas tut. Daten darstellen, Fragmente einblenden, Activities wechseln, Verbindungen herstellen, pipapo.
    Was macht also jede halbwegs intelligente Programmiersprache? Funktionszeiger. Closure. Block. Irgendsowas.
    Irgendwas, das die Implementierung aufrufen kann, wenn das gekoppelte Ereignis eintritt.


    Java möchte dafür ein eigenes Objekt. Ein Objekt, das nur die eine Aufgabe hat, den Klick zu verarbeiten. Und dafür dann mindestens eine weitere Abhängigkeit benötigt. Warum ist das Bullshit?


    Für die eine einzige Aufgabe 'Klick verarbeiten' werden mehrere unterschiedliche Objekte benutzt. Sie sind zwar im Detail unterschiedlich implementiert, aber Implementierungsdetail dürfte in dem Fall keine Rolle spielen. Ein 'HandleOnClick' Objekt sollte immer einen OnClick handeln. Warum gibt es dann mehrere 'HandleOnClick' Objekte? Die OnClicks müssen unterschiedlich gehandelt werden.


    Du argumentierst, dass es nahezu unmöglich ist, dass ein OnClick dasselbe machen soll wie ein anderes OnClick. Weiterhin argumentierst Du, dass das OnClick viele Abhängigkeiten zur implementierenden Klasse hat.
    Damit argumentierst Du ganz eindeutig gegen die Nutzung eines eigenen Objektes für die Implementierung des OnClickListeners.


    Im Prinzip argumentierst Du also für die Nutzung des onClick Parameters in der XML als Äquivalent zum Funktionszeiger.

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!