Frage

Ich übe für eine Prüfung und habe eine Beispielaufgabe gefunden, die mich völlig verwirrt.Ermitteln Sie für den folgenden Code die Ausgabe:

class Moe {
    public void print(Moe p) {
        System.out.println("Moe 1\n");
    }
}
class Larry extends Moe {
    public void print(Moe p) {
        System.out.println("Larry 1\n");
    }
    public void print(Larry l) {
        System.out.println("Larry 2\n");
    }
}
class Curly extends Larry {
    public void print(Moe p) {
        System.out.println("Curly 1\n");
    }
    public void print(Larry l) {
        System.out.println("Curly 2\n");
    }
    public void print(Curly b) {
        System.out.println("Curly 3\n");
    }
}
public class Overloading_Final_Exam {
    public static void main (String [] args) {
        Larry stooge1 = new Curly();
        Moe stooge2 = new Larry();
        Moe stooge3 = new Curly();
        Curly stooge4 = new Curly();
        Larry stooge5 = new Larry();
        stooge1.print(new Moe()); 
        ((Curly)stooge1).print(new Larry()); 
        ((Larry)stooge2).print(new Moe()); 
        stooge2.print(new Curly()); 
        stooge3.print(new Curly()); 
        stooge3.print(new Moe()); 
        stooge3.print(new Larry()); 
        ((Curly)stooge3).print(new Larry()); 
        ((Curly)stooge3).print(new Curly()); 
        stooge4.print(new Curly()); 
        stooge4.print(new Moe()); 
        stooge4.print(new Larry()); 
        stooge5.print(new Curly()); 
        stooge5.print(new Larry()); 
        stooge5.print(new Moe()); 
    }
}

Ich hatte meine Ideen im Kopf, aber als ich dann Java ausführte, kam mir etwas völlig anderes in den Sinn:

Curly 1
Curly 2
Larry 1
Larry 1
Curly 1
Curly 1
Curly 1
Curly 2
Curly 3
Curly 3
Curly 1
Curly 2
Larry 2
Larry 2
Larry 1

Die ersten paar sind in Ordnung, aber dann verstehe ich es wirklich nicht.Hat jemand eine gute Erklärung für dieses Problem?

Danke

War es hilfreich?

Lösung

Ich würde beginnen, indem Zeichnung ein Bild ...

Moe - print(Moe)
 |
Larry - print(Moe), print(Larry)
 |
Curly - print(Moe), print(Larry), print(Curly)

Dann würde ich den Überblick über die Variablen halten:

  • Larry - stooge1 -> Curly
  • Moe - stooge2 -> Larry
  • Moe - stooge3 -> Curly
  • Curly - stooge4 -> Curly
  • Larry - stooge5 -> Larry

  • stooge1.print(new Moe())

    • stooge1 -> Curly so nennt Curly.print (Moe)
  • ((Curly)stooge1).print(new Larry());

    • stooge1 -> Curly so ruft Curly.print (neu Larry ())
  • ((Larry)stooge2).print(new Moe());

    • stooge2 -> Larry so nennt Larry.print (neu Moe ());
  • stooge2.print(new Curly());
    Ok, das ist, wo es ein bisschen schwieriger wird (leider habe ich aufgehört man vor hier)

    • stooge2 erklärt ein Moe zu sein. Also, wenn der Compiler sucht, was es nennen wird den Druck (Moe) Methode aufzurufen. Dann zur Laufzeit weiß er, dass stooge2 ist ein Larry, damit es die Larry.print (Moe) Methode aufruft.

etc ...

Lassen Sie mich wissen, wenn folgt, den ganzen Weg durch für Sie arbeiten nicht aus.

(aktualisiert das nächste zu klären)

So die allgemeine Regel lautet:

  • sucht der Compiler in der Variablentyp zu entscheiden, welche Methode aufzurufen.
  • sucht die Laufzeit bei der aktuellen Klasse, die die variable Punkt ist zu entscheiden, wo von der Methode zu erhalten.

Also, wenn Sie haben:

Moe stooge2 = new Larry();
stooge2.print(new Moe());

Der Compiler sagt:

  • kann Larry stooge2 zugewiesen werden? (Ja als Larry ist eine Unterklasse von Moe)
  • hat Moe einen Druck (Moe) Methode? (Ja)

die Laufzeit sagt:

  • Ich soll auf diese hier den Druck (Moe) Methode aufrufen Objekt ... stooge2
  • stooge2 ist Punkt an einer Larry.
  • Ich werde den Druck (Moe) -Methode in der Larry-Klasse aufrufen.

Wenn Sie gearbeitet haben, dass alle versuchen, aus einige der Methoden loszuwerden und sehen, wie sich das ändert Dinge.

Andere Tipps

Tatsächlich ist dieses Problem nicht so einfach, wie es scheint, da Java sowohl statisch als auch dynamisch gebunden ist.Sie müssen verstehen, wo die einzelnen Elemente angewendet werden, bevor Sie alle Ergebnisse verstehen, die Sie mit dieser Übung erzielen.

Die von TofuBeer erwähnte allgemeine Regel ist nur im Fall der dynamischen Bindung korrekt.Bei der statischen Bindung werden Entscheidungen erst zur Kompilierungszeit getroffen.

Ihr Beispiel mischt die dynamische Bindung (wenn Methoden überschrieben werden) und die statische Bindung (wenn Methoden überladen werden).

Schau mal bei dieser Frage für mehr Details.

Ein Hinweis ist der Wert auf der linken Seite außer Acht zu lassen, wenn sie bei Objekten suchen. Stattdessen während der Erklärung auf dem Wert des rechten suchen, ist dies der tatsächliche Wert des Objekts.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top