Code-Wiederholungen entfernen (Methoden- und Konstruktorüberladung)
Kehren wir noch einmal zu unserer Person
-Klasse zurück. Sie sieht derzeit so aus:
public class Person {
private String name;
private int age;
private int height;
private int weight;
public Person(String name) {
this.name = name;
this.age = 0;
this.weight = 0;
this.height = 0;
}
public void printPerson() {
System.out.println(this.name + " is " + this.age + " years old");
}
public void growOlder() {
this.age++;
}
public boolean isAdult() {
if (this.age < 18) {
return false;
}
return true;
}
public double bodyMassIndex() {
double heightInMeters = this.height / 100.0;
return this.weight / (heightInMeters * heightInMeters);
}
public String toString() {
return this.name + " is " + this.age + " years old, their BMI is " + this.bodyMassIndex();
}
public void setHeight(int height) {
this.height = height;
}
public int getHeight() {
return this.height;
}
public int getWeight() {
return this.weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getName() {
return this.name;
}
}
Alle Personenobjekte sind bei ihrer Erstellung 0 Jahre alt. Dies liegt daran, dass der Konstruktor den Wert der Instanzvariablen age
auf 0 setzt:
public Person(String name) {
this.name = name;
this.age = 0;
this.weight = 0;
this.height = 0;
}
Konstruktorüberladung
Wir möchten auch die Möglichkeit haben, Personen so zu erstellen, dass der Konstruktor sowohl das Alter als auch den Namen als Parameter erhält. Dies ist möglich, da eine Klasse mehrere Konstruktoren haben kann.
Lassen Sie uns einen alternativen Konstruktor erstellen. Der alte Konstruktor kann beibehalten werden.
public Person(String name) {
this.name = name;
this.age = 0;
this.weight = 0;
this.height = 0;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
this.weight = 0;
this.height = 0;
}
Wir haben jetzt zwei alternative Möglichkeiten, Objekte zu erstellen:
public static void main(String[] args) {
Person paul = new Person("Paul", 24);
Person ada = new Person("Ada");
System.out.println(paul);
System.out.println(ada);
}
Paul is 24 years old. Ada is 0 years old.
Die Technik, mehrere Konstruktoren in einer Klasse zu haben, wird als Konstruktorüberladung bezeichnet. Eine Klasse kann mehrere Konstruktoren haben, die sich in der Anzahl und/oder Art ihrer Parameter unterscheiden. Es ist jedoch nicht möglich, zwei Konstruktoren mit genau denselben Parametern zu haben.
Wir können beispielsweise keinen public Person(String name, int weight)
-Konstruktor hinzufügen, da es für Java unmöglich wäre, zwischen diesem und dem Konstruktor mit zwei Parametern, bei dem der int-Parameter für das Alter verwendet wird, zu unterscheiden.
Aufruf des eigenen Konstruktors
Moment mal. Wir hatten zuvor festgestellt, dass „Copy-Paste“-Code keine gute Idee ist. Wenn Sie sich die überladenen Konstruktoren oben ansehen, haben sie viel gemeinsam. Wir sind damit nicht zufrieden.
Der erste Konstruktor – der, der einen Namen als Parameter erhält – ist in der Tat ein Spezialfall des zweiten Konstruktors – desjenigen, der sowohl Name als auch Alter erhält. Was wäre, wenn der erste Konstruktor den zweiten Konstruktor aufrufen könnte?
Dies ist möglich. Ein Konstruktor kann von einem anderen Konstruktor mit dem Schlüsselwort this
aufgerufen werden, das sich auf das betreffende Objekt bezieht!
Lassen Sie uns den ersten Konstruktor so modifizieren, dass er selbst nichts tut, sondern stattdessen den zweiten Konstruktor aufruft und ihn bittet, das Alter auf 0 zu setzen.
public Person(String name) {
this(name, 0);
//hier wird der Code des zweiten Konstruktors ausgeführt, und das Alter wird auf 0 gesetzt
}
public Person(String name, int age) {
this.name = name;
this.age = age;
this.weight = 0;
this.height = 0;
}
Der Aufruf des Konstruktors this(name, 0);
mag etwas seltsam erscheinen. Man kann sich das so vorstellen, dass der Aufruf automatisch durch „Copy-Paste“ des zweiten Konstruktors ersetzt wird, wobei der Parameter age
auf 0 gesetzt wird. NB! Wenn ein Konstruktor einen anderen Konstruktor aufruft, muss der Aufruf des Konstruktors der erste Befehl im Konstruktor sein.
Neue Objekte können wie zuvor erstellt werden:
public static void main(String[] args) {
Person paul = new Person("Paul", 24);
Person eve = new Person("Eve");
System.out.println(paul);
System.out.println(eve);
}
Paul is 24 years old. Eve is 0 years old.
Methodenüberladung
Methoden können auf die gleiche Weise wie Konstruktoren überladen werden, d. h., es können mehrere Versionen einer bestimmten Methode erstellt werden. Auch hier müssen sich die Parameter der verschiedenen Versionen unterscheiden. Lassen Sie uns eine weitere Version der Methode growOlder
erstellen, die die Person um die Anzahl der ihr als Parameter übergebenen Jahre älter macht.
public void growOlder() {
this.age = this.age + 1;
}
public void growOlder(int years) {
this.age = this.age + years;
}
Im folgenden Beispiel wird "Paul" mit 24 Jahren geboren, altert um ein Jahr und dann um 10 Jahre:
public static void main(String[] args) {
Person paul = new Person("Paul", 24);
System.out.println(paul);
paul.growOlder();
System.out.println(paul);
paul.growOlder(10);
System.out.println(paul);
}
Es wird ausgegeben:
Paul is 24 years old. Paul is 25 years old. Paul is 35 years old.
Eine Person
hat nun zwei Methoden, die beide growOlder
heißen. Welche von beiden ausgeführt wird, hängt von der Anzahl der übergebenen Parameter ab.
Wir können das Programm auch so modifizieren, dass die parameterlose Methode mit der Methode growOlder(int years)
implementiert wird:
public void growOlder() {
this.growOlder(1);
}
public void growOlder(int years) {
this.age = this.age + years;
}