CodeGym/Java-Blog/Random-DE/Methoden in Java
Autor
John Selawsky
Senior Java Developer and Tutor at LearningTree

Methoden in Java

Veröffentlicht in der Gruppe Random-DE
Hallo wieder! In der letzten Lektion haben wir uns mit Klassen und Konstruktoren vertraut gemacht und gelernt, wie man eigene erstellt. Heute werden wir uns mit Java-Methoden, einem wesentlichen Bestandteil von Klassen, besser vertraut machen. Eine Methode in Java ist eine Reihe von Befehlen, mit denen Sie eine bestimmte Operation in einem Programm ausführen können. Mit anderen Worten: Eine Methode ist eine Funktion; etwas, wozu Ihre Klasse in der Lage ist. In anderen Programmiersprachen werden Methoden oft als „Funktionen“ bezeichnet, in Java ist das Wort „Methode“ jedoch häufiger anzutreffen. :) Wenn Sie sich erinnern, haben wir in der letzten Lektion einfache Methoden für eine Katzenklasse erstellt , damit unsere Katzen miauen und springen können:
public class Cat {

    String name;
    int age;

    public void sayMeow() {
        System.out.println("Meow!");
    }

    public void jump() {
        System.out.println("Pounce!");
    }

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";

        smudge.sayMeow();
        smudge.jump();
    }
}
sayMeow() und jump() sind Methoden unserer Klasse. Und das Ausführen dieser Methoden führt zu der folgenden Konsolenausgabe:
Meow!
Pounce!
Unsere Methoden sind recht einfach: Sie geben einfach Text an die Konsole aus. Aber in Java haben Methoden eine wichtige Aufgabe: Sie führen Aktionen an den Daten eines Objekts aus. Sie verändern die Daten des Objekts, transformieren es, zeigen es an und machen andere Dinge damit. Unsere aktuellen Methoden machen nichts mit den Daten des Cat- Objekts. Schauen wir uns ein anschaulicheres Beispiel an:
public class Truck {

    int length;
    int width;
    int height;
    int weight;

    public int getVolume() {
        int volume = length * width * height;
        return volume;
    }
}
Hier haben wir zum Beispiel eine Klasse, die einen Truck darstellt . Der Sattelschlepper hat eine Länge, Breite, Höhe und ein Gewicht (die wir später benötigen). In der Methode getVolume() führen wir Berechnungen durch und wandeln die Daten unseres Objekts in eine Zahl um, die sein Volumen darstellt (wir multiplizieren Länge, Breite und Höhe). Diese Zahl ist das Ergebnis der Methode. Beachten Sie, dass die Deklaration der Methode als public int getVolume geschrieben ist . Das bedeutet, dass diese Methode ein int zurückgeben muss . Wir haben den Rückgabewert der Methode berechnet und müssen ihn nun an das Programm zurückgeben, das unsere Methode aufgerufen hat. Um das Ergebnis einer Methode in Java zurückzugeben, verwenden wir das Schlüsselwort return. Rücklaufvolumen;

Java-Methodenparameter

Wir können Werte, die „Argumente“ genannt werden, an eine Methode übergeben, wenn wir sie aufrufen. Die Deklaration einer Methode enthält eine Liste von Variablen, die uns den Typ und die Reihenfolge der Variablen mitteilen, die die Methode akzeptieren kann. Diese Liste wird als „Methodenparameter“ bezeichnet. Die getVolume()- Methode unserer Truck- Klasse definiert derzeit keine Parameter, also versuchen wir, unser Truck-Beispiel zu erweitern. Erstellen Sie eine neue Klasse mit dem Namen BridgeOfficer . Hierbei handelt es sich um einen an einer Brücke diensthabenden Polizisten, der alle vorbeifahrenden Lastwagen daraufhin kontrolliert, ob deren Ladung das zulässige Gewicht überschreitet.
public class BridgeOfficer {

    int maxWeight;

    public BridgeOfficer(int normalWeight) {
        this.maxWeight = normalWeight;
    }

    public boolean checkTruck(Truck truck) {
        if (truck.weight > maxWeight) {
            return false;
        } else {
            return true;
        }
    }
}
Die checkTruck- Methode akzeptiert ein Argument, ein Truck- Objekt, und bestimmt, ob der Beamte den LKW auf die Brücke lässt oder nicht. Die Logik innerhalb der Methode ist recht einfach: Wenn das Gewicht des LKWs das maximal zulässige Gewicht überschreitet, gibt die Methode false zurück . Es muss eine andere Straße gefunden werden :( Wenn das Gewicht kleiner oder gleich dem Maximum ist, kann es bestehen und die Methode gibt true zurück. Wenn Sie die Ausdrücke „zurückgeben“ oder „die Methode gibt einen Wert zurück“ noch nicht vollständig verstehen, machen wir eine Pause vom Programmieren und betrachten sie anhand eines einfachen Beispiels aus dem wirklichen Leben. :) Nehmen wir an, Sie werden krank und bleiben ein paar Tage von der Arbeit zu Hause. Sie gehen mit Ihrem ärztlichen Attest zur Buchhaltung, denn der Krankenstand soll bezahlt werden. Wenn wir diese Situation mit Methoden vergleichen, dann hat der Buchhalter eine paySickLeave()Methode. Als Argument für diese Methode geben Sie ein ärztliches Attest an (ohne dieses wird die Methode nicht funktionieren und Sie werden nicht bezahlt!). Dann werden innerhalb der Methode die notwendigen Berechnungen anhand Ihrer Notiz durchgeführt (der Buchhalter berechnet daraus, wie viel das Unternehmen Ihnen zahlen soll), und das Ergebnis Ihrer Arbeit (ein Geldbetrag) wird Ihnen zurückgegeben. Unser Programm funktioniert ähnlich. Es ruft eine Methode auf, übergibt ihr Daten und erhält schließlich ein Ergebnis. Hier ist die main() -Methode unseres BridgeOfficer- Programms :
public static void main(String[] args) {
    Truck first = new Truck();
    first.weight = 10000;
    Truck second = new Truck();
    second.weight = 20000;

    BridgeOfficer officer = new BridgeOfficer(15000);
    System.out.println("Truck 1! Can I go, officer?");
    boolean canFirstTruckGo = officer.checkTruck(first);
    System.out.println(canFirstTruckGo);

    System.out.println();

    System.out.println("Truck 2! And can I?");
    boolean canSecondTruckGo = officer.checkTruck(second);
    System.out.println(canSecondTruckGo);
}
Wir bauen zwei Lkw mit 10.000 und 20.000 Ladungen. Und die Brücke, auf der der Beamte arbeitet, hat ein maximales Gewicht von 15.000. Das Programm ruft die Methode Officer.checkTruck(first) auf . Die Methode berechnet alles und gibt dann true zurück, den das Programm dann in der booleschen Variablen canFirstTruckGo speichert . Jetzt können Sie damit machen, was Sie wollen (genau wie mit dem Geld, das Ihnen der Buchhalter gegeben hat). Am Ende des Tages der Code
boolean canFirstTruckGo = officer.checkTruck(first);
läuft darauf hinaus
boolean canFirstTruckGo =  true;
Hier ist ein sehr wichtiger Punkt: Die Return- Anweisung gibt nicht nur den Rückgabewert der Methode zurück, sie stoppt auch die Ausführung der Methode! Jeglicher Code, der nach der Return- Anweisung kommt, wird nicht ausgeführt!
public boolean checkTruck(Truck truck) {

    if (truck.weight > maxWeight) {
        return false;
        System.out.println("Turn around, you're overweight!");
    } else {
        return true;
        System.out.println("Everything looks good, go ahead!");
    }
}
Die Kommentare des Beamten werden nicht angezeigt, da die Methode bereits ein Ergebnis zurückgegeben und beendet wurde! Das Programm kehrt an die Stelle zurück, an der die Methode aufgerufen wurde. Darauf müssen Sie nicht achten: Der Java-Compiler ist intelligent genug, um einen Fehler zu generieren, wenn Sie versuchen, Code nach einer Return- Anweisung zu schreiben.

Avengers: Parameter War

Es gibt Situationen, in denen wir mehrere Möglichkeiten zum Aufrufen einer Methode benötigen. Warum nicht unsere eigene künstliche Intelligenz erschaffen? Amazon hat Alexa, Apple hat Siri, warum sollten wir also keine haben? :) Im Film Iron Man erschafft Tony Stark seine eigene unglaubliche künstliche Intelligenz, Jarvis. Lasst uns diesem großartigen Charakter Tribut zollen und unserer KI zu seinen Ehren einen Namen geben. :) Das erste, was wir tun müssen, ist, Jarvis beizubringen, die Leute zu begrüßen, die den Raum betreten (es wäre seltsam, wenn sich ein so erstaunlicher Intellekt als unhöflich erweisen würde).
public class Jarvis {

    public void sayHi(String name) {
        System.out.println("Good evening, " + name + ". How are you?");
    }

    public static void main(String[] args) {
        Jarvis jarvis = new Jarvis();
        jarvis.sayHi("Tony Stark");
    }
}
Konsolenausgabe:
Good evening, Tony Stark. How are you?
Sehr gut! Jarvis kann nun Gäste begrüßen. Natürlich wird es in den meisten Fällen sein Meister Tony Stark sein. Aber was ist, wenn er nicht alleine kommt! Unsere Methode sayHi() akzeptiert nur ein Argument. Daher kann es nur eine Person begrüßen, die den Raum betritt, und ignoriert die andere Person. Nicht sehr höflich, finden Sie nicht auch? :/

Überladen von Java-Methoden

In diesem Fall können wir das Problem lösen, indem wir einfach zwei Methoden mit demselben Namen, aber unterschiedlichen Parametern schreiben:
public class Jarvis {

    public void sayHi(String firstGuest) {
        System.out.println("Good evening, " + firstGuest + ". How are you?");
    }

    public void sayHi(String firstGuest, String secondGuest) {
        System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
    }
}
Dies wird als Methodenüberladung bezeichnet. Durch die Überladung von Methoden ist unser Programm flexibler und ermöglicht die Anpassung an verschiedene Arbeitsweisen. Sehen wir uns an, wie es funktioniert:
public class Jarvis {

    public void sayHi(String firstGuest) {
        System.out.println("Good evening, " + firstGuest + ". How are you?");
    }

    public void sayHi(String firstGuest, String secondGuest) {
        System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
    }

    public static void main(String[] args) {
        Jarvis jarvis = new Jarvis();
        jarvis.sayHi("Tony Stark");
        jarvis.sayHi("Tony Stark", "Captain America");
    }
}
Konsolenausgabe:
Good evening, Tony Stark. How are you?
Good evening, Tony Stark and Captain America. How are you?
Hervorragend, beide Versionen haben funktioniert. :) Aber wir haben das Problem nicht gelöst! Was ist, wenn drei Gäste anwesend sind? Wir könnten die Methode sayHi() natürlich noch einmal überladen, sodass sie drei Gastnamen akzeptiert. Aber es könnten auch 4 oder 5 sein. Bis ins Unendliche. Gibt es nicht eine bessere Möglichkeit, Jarvis beizubringen, mit einer beliebigen Anzahl von Namen umzugehen, ohne die Methode sayHi() millionenfach zu überlasten? :/ Natürlich gibt es das! Wenn das nicht der Fall wäre, glauben Sie, dass Java die beliebteste Programmiersprache der Welt wäre? ;)
public void sayHi(String...names) {

    for (String name: names) {
        System.out.println("Good evening, " + name + ". How are you?");
    }
}
Wenn ( String... Namen ) als Parameter verwendet wird, bedeutet dies, dass eine Sammlung von Strings an die Methode übergeben wird. Wir müssen nicht im Voraus angeben, wie viele es sein werden, daher ist unsere Methode jetzt viel flexibler:
public class Jarvis {

    public void sayHi(String...names) {
        for (String name: names) {
            System.out.println("Good evening, " + name + ". How are you?");
        }
    }

    public static void main(String[] args) {
        Jarvis jarvis = new Jarvis();
        jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
    }
}
Konsolenausgabe:
Good evening, Tony Stark. How are you?
Good evening, Captain America. How are you?
Good evening, Black Widow. How are you?
Good evening, Hulk. How are you?
Einige Codes hier werden Ihnen unbekannt sein, aber machen Sie sich darüber keine Sorgen. Im Kern ist es einfach: Die Methode nimmt nacheinander jeden Namen und begrüßt jeden Gast! Außerdem funktioniert es mit einer beliebigen Anzahl übergebener Zeichenfolgen! Zwei, zehn, sogar tausend – die Methode funktioniert bei beliebig vielen Gästen. Viel bequemer, als die Methode mit all den Möglichkeiten zu überladen, finden Sie nicht? :) Hier noch ein wichtiger Punkt: Auf die Reihenfolge der Argumente kommt es an! Nehmen wir an, unsere Methode benötigt einen String und eine Zahl:
public class Person {

    public static void sayYourAge(String greeting, int age) {
        System.out.println(greeting + " " + age);
    }

    public static void main(String[] args) {
        sayYourAge("My age is ", 33);
        sayYourAge(33, "My age is "); // Error!
    }
}
Wenn die sayYourAge- Methode der Person- Klasse eine Zeichenfolge und eine Zahl als Eingaben akzeptiert, muss das Programm diese in dieser bestimmten Reihenfolge übergeben! Wenn wir sie in einer anderen Reihenfolge übergeben, generiert der Compiler einen Fehler und die Person kann ihr Alter nicht sagen. Übrigens sind auch Konstruktoren, die wir in der letzten Lektion behandelt haben, Methoden! Sie können sie auch überladen (dh mehrere Konstruktoren mit unterschiedlichen Parametersätzen erstellen) und die Reihenfolge der übergebenen Argumente ist auch für sie von grundlegender Bedeutung. Das sind echte Methoden! :) :)

Noch einmal zu den Parametern

Ja, tut mir leid, wir sind noch nicht damit fertig. :) Das Thema, das wir jetzt studieren werden, ist sehr wichtig. Die Wahrscheinlichkeit, dass Sie bei jedem zukünftigen Vorstellungsgespräch danach gefragt werden, liegt bei 90 %! Lassen Sie uns über die Übergabe von Argumenten an Methoden sprechen. Betrachten Sie ein einfaches Beispiel:
public class TimeMachine {

    public void goToFuture(int currentYear) {
        currentYear = currentYear+10;
    }

    public void goToPast(int currentYear) {
        currentYear = currentYear-10;
    }

    public static void main(String[] args) {
        TimeMachine timeMachine = new TimeMachine();
        int currentYear = 2018;

        System.out.println("What year is it?");
        System.out.println(currentYear);

        timeMachine.goToPast(currentYear);
        System.out.println("How about now?");
        System.out.println(currentYear);
    }
}
Die Zeitmaschine verfügt über zwei Methoden. Beide nehmen die Zahl, die das aktuelle Jahr darstellt, als Eingabe und erhöhen oder verringern ihren Wert (je nachdem, ob wir in die Vergangenheit oder in die Zukunft gehen möchten). Aber wie Sie der Konsolenausgabe entnehmen können, funktioniert die Methode nicht! Konsolenausgabe:
What year is it?
2018
How about now?
2018
Wir haben die Variable currentYear an die Methode goToPast() übergeben , ihr Wert hat sich jedoch nicht geändert. Wir waren im Jahr 2018 und hier sind wir geblieben. Aber warum? :/ Weil Grundelemente in Java als Wert an Methoden übergeben werden. Was bedeutet das? Wenn wir die Methode goToPast() aufrufen und ihr die int -Variable currentYear (=2018) übergeben , erhält die Methode nicht die Variable currentYear selbst, sondern eine Kopie davon. Natürlich ist der Wert dieser Kopie auch 2018, aber etwaige Änderungen an der Kopie haben keinerlei Auswirkungen auf unsere ursprüngliche Variable „currentYear “! Machen wir unseren Code expliziter und beobachten, was mit currentYear passiert:
public class TimeMachine {

    public void goToFuture(int currentYear) {
        currentYear = currentYear+10;
    }

    public void goToPast(int currentYear) {
        System.out.println("The goToPast method has started running!");
        System.out.println("currentYear inside the goToPast method (at the beginning) = " + currentYear);
        currentYear = currentYear-10;
        System.out.println("currentYear inside the goToPast method (at the end) = " + currentYear);
    }

    public static void main(String[] args) {
        TimeMachine timeMachine = new TimeMachine();
        int currentYear = 2018;

        System.out.println("What was the year when the program started?");
        System.out.println(currentYear);

        timeMachine.goToPast(currentYear);
        System.out.println("And what year is it now?");
        System.out.println(currentYear);
    }
}
Konsolenausgabe:
What was the year when the program started?
2018
The goToPast method has started running!
currentYear inside the goToPast method (at the beginning) = 2018
currentYear inside the goToPast method (at the end) = 2008
And what year is it now?
2018
Dies zeigt deutlich, dass die an die Methode goToPast() übergebene Variable nur eine Kopie von currentYear ist . Und das Ändern der Kopie hat keinen Einfluss auf den „Original“-Wert. „Pass by reference“ bedeutet genau das Gegenteil. Lasst uns an Katzen üben! Ich meine, mal sehen, wie die Referenzübergabe anhand eines Katzenbeispiels aussieht. :) :)
public class Cat {

    int age;

    public Cat(int age) {
        this.age = age;
    }
}
Jetzt schicken wir mit Hilfe unserer Zeitmaschine Smudge , die erste zeitreisende Katze der Welt, in die Vergangenheit und die Zukunft! Ändern wir die TimeMachine- Klasse so, dass sie mit Cat- Objekten funktioniert .
public class TimeMachine {

    public void goToFuture(Cat cat) {
        cat.age += 10;
    }

    public void goToPast(Cat cat) {
        cat.age -= 10;
    }
}
Jetzt ändern die Methoden nicht nur die übergebene Nummer. Vielmehr ändern sie das Altersfeld dieser spezifischen Katze . Sie werden sich erinnern, dass dies bei uns mit Grundelementen nicht funktioniert hat, da sich die ursprüngliche Zahl nicht geändert hat. Mal sehen, was passieren wird!
public static void main(String[] args) {

    TimeMachine timeMachine = new TimeMachine();
    Cat smudge = new Cat(5);

    System.out.println("How old was Smudge when the program started?");
    System.out.println(smudge.age);

    timeMachine.goToFuture(smudge);
    System.out.println("How about now?");
    System.out.println(smudge.age);

    System.out.println("Holy smokes! Smudge has aged 10 years! Back up quickly!");
    timeMachine.goToPast(smudge);
    System.out.println("Did it work? Have we returned the cat to its original age?");
    System.out.println(smudge.age);
}
Konsolenausgabe:
How old was Smudge when the program started running?
5
How about now?
15
Holy smokes! Smudge has aged 10 years! Back up quickly!
Did it work? Have we returned the cat to its original age?
5
Wow! Jetzt hat die Methode etwas anderes bewirkt: Unsere Katze ist drastisch gealtert, aber dann ist sie wieder jung geworden! :) Versuchen wir herauszufinden, warum. Anders als im Beispiel mit Grundelementen werden Objekte bei der Übergabe an eine Methode als Referenz übergeben. Ein Verweis auf das ursprüngliche Smudge- Objekt wurde an die Methode changeAge() übergeben . Wenn wir also smudge.age innerhalb der Methode ändern, verweisen wir auf denselben Speicherbereich, in dem unser Objekt gespeichert ist. Es ist eine Anspielung auf denselben Smudge, den wir ursprünglich erstellt haben. Dies nennt man „Referenzübergabe“! Allerdings ist nicht alles mit Referenzen so einfach. :) Versuchen wir, unser Beispiel zu ändern:
public class TimeMachine {

    public void goToFuture(Cat cat) {
        cat = new Cat(cat.age);
        cat.age += 10;
    }

    public void goToPast(Cat cat) {
        cat = new Cat(cat.age);
        cat.age -= 10;
    }

    public static void main(String[] args) {
        TimeMachine timeMachine = new TimeMachine();
        Cat smudge = new Cat(5);

        System.out.println("How old was Smudge when the program started?");
        System.out.println(smudge.age);

        timeMachine.goToFuture(smudge);
        System.out.println ("Smudge went to the future! Has his age changed?");
        System.out.println(smudge.age);

        System.out.println ("And if you try going back?");
        timeMachine.goToPast(smudge);
        System.out.println(smudge.age);
    }
}
Konsolenausgabe:
How old was Smudge when the program started running?
5
Smudge went to the future! Has his age changed?
5
And if you try going back?
5
Es funktioniert wieder nicht! О_О Lassen Sie uns herausfinden, was passiert ist. :) Es hat alles mit den goToPast- / goToFuture- Methoden und der Funktionsweise von Referenzen zu tun. Jetzt bitte um Ihre Aufmerksamkeit! Dies ist das Wichtigste, um zu verstehen, wie Referenzen und Methoden funktionieren. Tatsache ist, dass wenn wir die Methode goToFuture(Cat cat) aufrufen , eine Kopie der Referenz auf das Cat-Objekt übergeben wird, nicht die Referenz selbst. Wenn wir also ein Objekt an eine Methode übergeben, gibt es zwei Referenzen auf das Objekt. Dies ist sehr wichtig, um zu verstehen, was passiert. Genau aus diesem Grund hat sich das Alter der Katze in unserem letzten Beispiel nicht verändert. Im vorherigen Beispiel haben wir beim Ändern des Alters einfach die Referenz verwendet, die an goToFuture() übergeben wurde.Methode und verwendete sie, um das Objekt im Speicher zu finden und sein Alter zu ändern ( cat.age += 10 ). Aber jetzt erstellen wir innerhalb der goToFuture()- Methode ein neues Objekt ( cat = new Cat(cat.age) ), und diesem Objekt wird dieselbe Referenzkopie zugewiesen, die an die Methode übergeben wurde. Infolge:
  • Die erste Referenz ( Cat smudge = new Cat (5) ) verweist auf die ursprüngliche Katze (mit Alter 5)
  • Als wir danach der Variablen cat die Methode goToPast() übergeben und ihr ein neues Objekt zugewiesen haben, wurde die Referenz kopiert.
Und das brachte uns zum Endergebnis: zwei Referenzen, die auf zwei verschiedene Objekte verweisen. Aber wir haben nur das Alter eines von ihnen geändert (desjenigen, das innerhalb der Methode erstellt wurde).
cat.age += 10;
Und natürlich können wir in der Methode main() auf der Konsole sehen, dass sich das Alter der Katze, smudge.age , nicht geändert hat. Schließlich ist smudge eine Referenzvariable, die immer noch auf das alte, ursprüngliche Objekt mit Alter 5 verweist, und wir haben mit diesem Objekt nichts gemacht. Alle unsere Altersänderungen wurden am neuen Objekt vorgenommen. Es stellt sich also heraus, dass Objekte per Referenz an Methoden übergeben werden. Kopien von Objekten werden niemals automatisch erstellt. Wenn Sie ein Katzenobjekt an eine Methode übergeben und sein Alter ändern, ändern Sie auch sein Alter. Referenzvariablen werden jedoch beim Zuweisen von Werten und/oder beim Aufrufen von Methoden kopiert! Wiederholen wir hier, was wir über die Übergabe von Grundelementen gesagt haben: „Wenn wir die Methode changeInt() aufrufen und den int übergebenVariable x (=15) , ruft die Methode nicht die x- Variable selbst ab, sondern eine Kopie davon. Daher haben alle an der Kopie vorgenommenen Änderungen keinen Einfluss auf unser Original xIch werde immer noch mehr als einmal darüber streiten, wie Argumente in Java übergeben werden (selbst unter erfahrenen Entwicklern). Aber jetzt wissen Sie genau, wie es funktioniert. Weiter so! :) :) Um das Gelernte zu vertiefen, empfehlen wir Ihnen, sich eine Videolektion aus unserem Java-Kurs anzusehen
Kommentare
  • Beliebt
  • Neu
  • Alt
Du musst angemeldet sein, um einen Kommentar schreiben zu können
Auf dieser Seite gibt es noch keine Kommentare