2016-04-05 11 views
2

Ich lerne derzeit Java-Klassen und Objekte von java tutorial oracle und habe die folgenden Anweisungen und Code festgestellt. Ich verstehe das Konzept, aber ich weiß nicht, warum wir eine Methode nicht überschreiben und definieren können, um eine Superklasse der ursprünglichen Methode zurückzugeben. Was ist der Grund dafür? Könnte mich bitte jemand aufklären? Vielen Dank im Voraus für jede Hilfe!Warum können wir eine Methode nicht überschreiben und sie so definieren, dass sie eine Oberklasse der ursprünglichen Methode zurückgibt?

Sie können eine Methode außer Kraft setzen und definieren es eine Unterklasse der ursprünglichen Methode zurückzukehren, wie folgt aus:

public Number returnANumber() { 
    ... 
} 

Aufschalten ursprüngliche Methode:

public ImaginaryNumber returnANumber() { 
    ... 
} 
+3

@KevinEsche, das ist nicht ganz genau. Sie können eine Methode überschreiben, um eine Unterklasse zurückzugeben. – shmosel

+0

@smossel Ja, du hast Recht mein Schlechter – SomeJavaGuy

+2

Das Tutorial erklärt bereits warum nicht: _Ein Objekt ist jedoch nicht unbedingt eine Zahl - es könnte ein String oder ein anderer Typ sein._ – Joni

Antwort

4

Stellen Sie sich vor, wenn es möglich war:

public class CarFactory { 
    Car giveMeACar() { ... }; 
} 

public class SpecialCarFactory extends CarFactory { 
    @Override 
    Object giveMeACar() { 
     return "hello world"; 
    } 
) 

public class Driver { 
    void drive() { 
     CarFactory carFactory = new SpecialCarFactory(); 

     Car car = carFactory.giveMeACar(); 
     // err, wait, sorry, can't do that. 
     // This car factory, despite its name, doesn't produce cars. 
     // It produces objects, and I've heard they're just 
     // "hello world" strings. Good luck driving a "hello world" 
     // string on a highway! 
    } 
} 

See, es ist nur ein Vertrag Sache. Wenn Sie in ein Café gehen, erwarten Sie, dass es Kaffee verkauft. Etwas kann nicht "ein Coffee-Shop" genannt werden, wenn es diesen Vertrag nicht erfüllt: Ein Coffee-Shop muss Kaffee verkaufen. Es kann gemolkenen Kaffee verkaufen, denn ein gemolkener Kaffee ist immer noch ein Kaffee. (Genau wie eine Autofabrik kann Toyota nur produzieren, weil Toyota ein Auto ist, und Sie können einen Toyota wie jedes andere Auto, fahren, ohne sogar zu wissen, dass es ein Toyota ist: das ist Polymorphismus).

0

Es spielt keine‘ Es ist sinnvoll, eine Methode zu überschreiben, um eine "allgemeinere" Klasse (dh eine Oberklasse) zurückzugeben, da Sie in diesem Fall den "Vertrag" brechen, indem Sie "mindestens" eine 01 zurückgebenr mit seiner entsprechenden Funktionalität. Wenn plötzlich jemand diese Methode überspringt, um nur eine reguläre Number zurückzugeben, brechen die Aufrufer dieser Methode ab, da sie darauf angewiesen sind, eine ImaginaryNumber zu bekommen (vielleicht nennen sie etwas wie getImaginaryPart(), was für eine nicht-imaginäre Zahl keinen Sinn ergibt).

Der umgekehrte Weg (z. B. das Zurückgeben einer Unterklasse, dh einer spezifischeren Klasse) bricht den Vertrag nicht, weil die Unterklasse mindestens die gleiche Funktionalität wie die Oberklasse besitzt.

0

Wenn jemand Code schreibt, der die Super-Klasse verwendet, verlassen sie sich nur auf den von der Super-Klasse definierten Vertrag.

So kann man so etwas schreiben:

SuperClass instance = ... 
Number num = instance.returnANumber(); 

Nun instance kann eine Instanz von jeder Unterklasse von SuperClass sein, returnNumber() einige davon außer Kraft setzen kann. Wenn die überschreibende Methode eine Unterklasse von Number zurückgibt, gibt sie immer noch eine Number zurück (jede Unterklasse von Number ist immer noch eine Number), so dass die Zuweisung immer noch gültig ist. Wenn die überschreibende Methode eine Superklasse von Number zurückgeben könnte, wäre die Zuweisung nicht mehr gültig und daher nicht zulässig.