Kann man eine Methode als Variable speichern und danach noch verändern?

Bitte aktiviere JavaScript!
Hallo, meine Frage ist vielleicht etwas schwierig zu erklären.
Ich möchte eine Methode in einer Variable speichern, um sie Später wieder abzurufen!

Ich weiß das man das so machen kann,
Code:
public void test(String s) { System.out.println(s) }
allerdings möchte Ich den Inhalt der Methode im nachhinein verändern können,
ungefähr wie im folgenden Beispiel
Code:
test() = new void(String s){ System.out.println(s); };
Falls jemand Fragen hat oder mein vorhaben nicht richtig versteht kann gerne Fragen!

Ich freue mich über alle Lösungsvorschläge!
 
Man kann eine Methode in einer Variablen speichern. Da hier Parameter übergeben werden aber nichts zurück gegeben wird, wurde dies Consumer genannt (Das übergebene wird konsumiert :) ).

Code kann dann z.B. wie folgt aussehen:
Java:
import java.util.function.Consumer;

public class Test {
    public static void main (String[] args) {
        Consumer<String> consumer;
        
        consumer = System.out::println;
        consumer.accept("Ausgabe!");
        
        consumer = s -> System.out.println("Hallo " + s);
        consumer.accept("Du");
    }
}
Also erst wird ein Consumer deklariert, der ein String Argument übergeben bekommt.
Dann wird der erst einmal auf die Method println von System.out gesetzt, so dass man beim Aufruf mittels accept "Ausgabe!" ausgegeben bekommt.
Dann setze ich das noch einmal um auf eine anonyme Funktion (Lambda Ausdruck), in der einfach "Hallo " + Argument ausgegeben wird, so dass dann im folgenden Aufruf "Hallo Du" ausgegeben wird.
 
Hey, danke für die Antwort, mit einem Consumer kann Ich schon etwas mehr Anfangen,

aber währe es möglich bei einem Consumer mehrere Zeilen bzw. "aufgaben" zu machen?

und meine Frage war vielleicht etwas kompliziert ausgedrückt,
Ich würde im Prinzip gerne Wissen ob man eine vorhandene Methode überschreiben bzw. den Inhalt neu festlegen kann.
wie im diesem Beispiel:
Code:
myVoid() = { System.out.println("test") }
 
Erst einmal etwas, das mir noch vor Deiner Antwort eingefallen ist - das Strategy Pattern. Das habe ich jetzt erst noch einmal zu Ende geschrieben, auch wenn es nicht auf Deine Antwort eingeht!

Was man in diesem Zusammenhang evtl. auch erwähnen sollte ist das Strategy Pattern. Das sollte man auf jeden Fall auch auf dem Schirm haben in solchen Situationen.

Beispiel aus head first design patterns ist die Ente, die ein Verhalten fürs fliegen und quaken hat.
Aber Enten gibt es viele, so z.B. neben der lebenden Ente noch die Badeente (kann nicht fliegen aber einen Quietsch Laut machen) oder die Holzente (kann weder fliegen noch Laute von sich geben).

Die Idee bei dem Pattern ist nun, dass die Ente ein Feld für das jeweilige Verhalten bekommt. Es gibt also ein Interface für das Fliegen und ein ein Interface für das quaken. Und davon leiten dann die jeweiligen Verhalten ab.

Auf Deine Frage bezogen bedeutet das, dass Du nicht eine Funktion setzt wie in meiner ersten Antwort, sondern Du nutzt ein Interface. Also in Deinem Fall ein Interface, das einfach nur eine Methode definiert.

Das Beispiel von oben etwas vereinfacht sieht dann wie folgt aus:
Interface:
Java:
package functiontest;

public interface ActionInterface {
    void doAction(String something);
}
Eine Implementierung:
Java:
package functiontest;

public class HelloOutputAction implements ActionInterface {
    public void doAction(String s) {
        System.out.println("Hello " + s);
    }
}
Das Beispiel von der ersten Antwort könnte dann wie folgt aussehen:

Java:
package functiontest;

import java.util.function.Consumer;

public class Test {
    public static void main (String[] args) {
        ActionInterface action;

        action = new ActionInterface() {
            @Override
            public void doAction(String something) {
                System.out.println(something);
            }
        };
        action.doAction("Ausgabe!");
        
        action = new HelloOutputAction();
        action.doAction("Du");

        Consumer<String> consumer;

        consumer = System.out::println;
        consumer.accept("Ausgabe!");

        consumer = s -> System.out.println("Hallo " + s);
        consumer.accept("Du");
    }
}
https://www.philipphauer.de/study/se/design-pattern/strategy.php
 
Hey, danke für die Antwort, mit einem Consumer kann Ich schon etwas mehr Anfangen,

aber währe es möglich bei einem Consumer mehrere Zeilen bzw. "aufgaben" zu machen?

und meine Frage war vielleicht etwas kompliziert ausgedrückt,
Ich würde im Prinzip gerne Wissen ob man eine vorhandene Methode überschreiben bzw. den Inhalt neu festlegen kann.
wie im diesem Beispiel:
Code:
myVoid() = { System.out.println("test") }
Also mehrere Zeilen bei einem Consumer ist kein Thema, denn Du kannst zum einen eine andere Funktion angeben (So wie bei dem System.out::println) und zum anderen kannst Du in einem Lambda auch einen Block nutzen, also sowas wie s -> { ... } .

Eine Funktion überschreiben geht so einfach erst einmal nicht. Hier gibt es aber auch Möglichkeiten, die z.B. bei der Aspekt Orientierten Entwicklung eingesetzt werden.
Da werden dann zum einen Proxy Objekte geschaffen, die gewisse Dinge machen... also angenommen, man hat eine Klasse Test, die nur eine Methode test hat, dann könnte ein Proxy so aussehen:

Java:
public class TestProxy extends Test {
    Test instance;

    public TestProxy(Test instance) {
        this.instance = instance;
    }

    public void test() {
        // Do something before call.
        instance.test();
        // Do something after call.
    }
}
Und zum anderen wird dann auch Bytecode angepasst. Der Code, der also mit der Klasse Test arbeitet, wird angepasst, so dass da immer der Proxy erstellt und genutzt wird.

Also da wo Du ein new Test() hast, wird ein new TestProxy(new Test())) raus.

Das dient dann um sogenannte Aspekte zu haben. Das sind dann Dinge, die z.B. vor oder nach einem Aufruf einer Methode gemacht werden sollen.

Das Ganze ist hier natürlich nur extrem vereinfacht dargestellt worden. Da kommt einiges mehr mit rein.

Was man sich hier ansehen kann und was Du evtl. nutzen willst, ist cglib: https://github.com/cglib/cglib/wiki
Das kann so Proxies erstellen und gewisse Dinge machen.

Ansonsten wenn es auch noch um Bytecode manipulation geht:
ASM: https://asm.ow2.io/

Und so Dich AOP interessieren sollte (weil ich es erwähnt habe): AspectJ ist ein AOP Framework: https://www.eclipse.org/aspectj/

Aber: Ich würde hier den Einsatz genau prüfen! Nicht, dass Du eine Sache unnötig verkomplizierst und so!
Das eigentliche Problem hast Du nicht genannt und daher fürchte ich etwas, dass wir hier eventuell ein xy Problem haben! Das Pattern ist im Software Design üblich und wenn das Overkill scheint: dann hat man den Consumer oder die Function, wenn man eine Rückgabe braucht....

Ich hoffe, dass dir dies etwas geholfen hat.

Edit: Hatte nicht mitbekommen, dass Du schon geantwortet hast. Schön, dass ich Dir etwas weiterhelfen konnte. Den Ausflug in die Proxies und Bytecode Manipulation kannst Du dann getrost ignorieren :)
 
Man könnte noch anführen, dass man komponierte Funktionen/Consumer erstellen kann:
Java:
import java.util.function.Consumer;

public class Test {
    public static void main(String[] args) {
        Consumer<String> output = printName().andThen(printLength()).andThen(newLine());
        output.accept("Hans");
        output.accept("Dampf");
    }

    private static Consumer<String> printName() {
        return s -> System.out.print("Dein Name '" + s + "' ");
    }

    private static Consumer<String> printLength() {
        return s -> System.out.print("ist " + s.length() + " Zeichen lang");
    }

    private static Consumer<String> newLine() {
        return s -> System.out.println();
    }
}
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben