Objekte und klasse |void?

7 Antworten

Da die Zähler und Nenner Global gespeichert werden. Sollte nun eine Funktion eine Zahl in dieser Globalen Variable speichern, kann nachfolgend jede Funktion diesen Wert nutzen.

Woher ich das weiß:eigene Erfahrung – Zu viel am Computer.

Die Antworten der anderen müssten eigentlich genügen.

Nur eine zusätzliche Idee: Ein Objekt ist eine Einheit mit eigenen Eigenschaften und Methoden. Das ist ein fundamentaler Unterschied zur imperativen Programmierung.

Ein Objekt hat eigene Eigenschaften, in Deinem Fall "zaehler" und "nenner". Diese Eigenschaften beschreiben den Zustand des Objekts (demnach ist "Bruch" ein denkbar ungeeignetes Beispiel für ein sinniges Objekt). Weiterhin hat ein Objekt Methoden, mit denen das Objekt lebt und nach außen kommuniziert. Die Objekt-internen Eigenschaften sind jedoch im "lebenden Objekt", können daher im Objekt verändert werden. Wenn ein Objekt Daten von außen holt (häufig set-Methoden, "Setter") oder sie nach außen gibt (häufig get-Methoden, "Getter") ist eine Kommunikation mit außen notwendig (wobei ich hier etwas untypisch das Objekt zum Client gemacht habe).

Insbesondere Get-Methoden haben Rückgabe-Werte. So kann man sich über das Objekt mit dem spezifischen Get die jeweilige Eigenschaft eines Objekts zeigen lassen.

Woher ich das weiß:eigene Erfahrung – Hobby und teilweise beruflich

Die Methode "kuerzen" gibt in diesem Fall nichts zurück. Sie verändert aber direkt die Instanz-Eigenschaften "zaehler" und "nenner", so dass diese per "ausgeben()" auf der Konsole ausgegeben werden können.

Man könnte die Methode auch statisch implementieren, so dass du Zähler und Nenner direkt an die kuerzen-Methode übergeben kannst, und als Rückgabewert den Ergebnis-String erhältst (public static String). Das hätte den Vorteil, dass du nicht zuerst eine Instanz der Bruch-Klasse erstellen musst, sondern die Methode direkt auf der Klasse Bruch aufrufen könntest, bspw: Bruch.kuerzen(15, 20):

class Bruch {
     public static String kuerzen(int zaehler, int nenner) {
        int m, n, r;
        m = zaehler;
        n = nenner;
        r = m % n;
        while (r > 0) {
            m = n;
            n = r;
            r = m % n;
        }
        zaehler /= n;
        nenner /= n;
        return Integer.toString(zaehler) + '/' + Integer.toString(nenner);
     }
}

Aufruf:

public class Test {
    public static void main(String args[]) {
        System.out.print(Bruch.kuerzen(15, 20));     // ergibt "3/4"
    }
}

Schachpapa  04.12.2019, 12:52

Welchen Sinn macht das kürzen, wenn man kein Bruch Objekt hat? Und wieso sollte das ein Vorteil sein?

Eine Methode, die kürzen heißt, sollte genau das tun: den Bruch, auf dem die Methode ausgeführt wird, kürzen. Der Bruch bleibt derselbe, nur eben gekürzt.

Man könnte vielleicht darüber nachdenken, eine Methode ggT mit zwei Parametern zu basteln, die ein int zurück gibt. Die benötigt tatsächlich keinen Bruch. Zum kürzen berechnet man dann zuerst den ggT(zähler, nenner) und teilt anschließend Zähler und Nenner durch diese Zahl.

Die schöne Formatierung als String gehört in eine toString Methode.

Dory1  04.12.2019, 13:03
@Schachpapa

Über die Sinnhaftigkeit einer "Bruch-Klasse" lässt sich vermutlich generell streiten :)

Bei meiner Antwort ging es auch vielmehr darum den Unterschied zwischen Instanz- und statischem Kontext zu vermitteln, und wie das ganze mit den vom Fragesteller erwähnten "Rückgabetypen" aussehen könnte.

Schachpapa  04.12.2019, 13:13
@Dory1

Die Bruch Klasse heißt in anderen Programmiersprachen z. B. Rational oder Fraction. Ist durchaus sinnvoll.

Ob dem Fragesteller an dieser Stelle der Hinweis auf das ihm mit Sicherheit noch unbekannte static etwas nützt, glaube ich eher nicht.

Dory1  04.12.2019, 13:19
@Schachpapa

Okay, ich verstehe deinen Punkt. Da kann ich nur hoffen den Fragesteller nicht noch zusätzlich verwirrt zu haben :)

Allgemein gilt immer: probier's aus! Tipp den Code ab und schau dir an, was passiert.

In diesem Fall gibt die funktion "gekuerztausgeben()" nichts zurück, die darin aufgerufene Funktion "ausgeben()" gibt den gekürzten Bruch aber auf der Konsole aus. Die Benennung von Dingen in dem Beispiel ist etwas unglücklich, aber

also es heißt das dort was berechnet wird und dass der Größte gemeinsamer Teiler ausgegeben werden soll als Rückgabetyp.

das behauptet keiner. Wenn das in dem Buch so steht, dann ist das falsch.

Und wenn du den Code ausprobierst, dann kannst du auch probieren, ob du die Methoden so verändert kriegst, dass dir der gekürzte Bruch als tatsächlicher Rückgabeparameter zurückgegeben wird.

Es muss nichts zurückgegeben werden, weil der Nenner innerhalb der Klasse direkt verändert wird. Du musst das so sehen: Eine Klasse ist nur eine Art Bauplan. Zum Beispiel ein Bauplan von einem Schiff. Es hat ein Ruder, ein Segel und noch mehr.

Um so ein Schiff zu erstellen, musst du es mit "new Schiff(rudel,segel,pipapo)" erstellen. Dies wäre dann ein Objekt der Klasse Schiff. Du kannst unterschiedliche Objekte erstellen, mit unterschiedlichen Eigenschaften.

Alle Schiffe haben aber die Methode ruderBewegen(). Wenn du nun schiffA.ruderBewegen aufrufst, verändert sich nur innerhalb des einen Objektes die ruder Eigenschaft. Dazu ist kein Rückgabewert nötig, da es im Objekt selbst umgeschrieben wird.