Sie verstehen möglicherweise, was ein "Cast" in Java ist.Mit Ausnahme von Umwandlungen, bei denen primitive Typen verwendet werden (z. B. das Umwandeln einer int
in eine float
), ändern die Umwandlungen Objekte überhaupt nicht.
Einer Ihrer Instanzvariablen ist
private Vector<Base> v;
(Bitte geben Sie die Java-Konvention verwenden und Klassennamen mit Großbuchstaben beginnen. Ich base
-Base
geändert habe ein gutes Beispiel zu geben.)
Die Objekte, die Sie in diesen Vektor einfügen, können vom Typ Base
oder einer Unterklasse vonBase
sein. Der Typ des Objekts ist festgelegt, wenn das Objekt erstellt wird. Angenommen Base
hat drei Unterklassen, Child1
, Child2
und Child3
. Diese Objekte können mit new Child1(...)
, new Child2(...)
, new Child3(...)
konstruiert werden. Sobald Sie new Child1(...)
sagen, haben Sie ein Objekt, dessen Typ Child1
ist, und Sie können nichts tun, um das zu ändern. Aber da eine Child1
eine Base
ist, können Sie Ihre Child1
überall verwenden, wo Sie eine Base
verwenden können, wie das Einfügen in Ihren Vektor v
.
Casting bewirkt nur, dass der Compiler eine Variable anders betrachtet. Angenommen, Sie sagen
Base x = v.get(i);
x
(wenn nicht null) ein Base
oder ein Objekt einer Unterklasse sein wird. Der Typ x
ist alles, was Sie zum Konstruieren des Objekts verwendet haben. Nun, wenn Sie sagen
Child1 y = (Child1)x;
Wenn x
ein Child1
ist, y
wird ein Verweis auf das gleiche Objekt wie x
sein. Aber der Compiler weiß, dass y
ein Child1
ist, und Sie können auf neue Methoden zugreifen, die in einem Child1
definiert sind. (Wenn x
kein Child1
ist, erhalten Sie eine Ausnahme.) Es ist jedoch wichtig zu beachten, dass eine Umwandlung kein neues Objekt erstellt und den Typ von nichts ändert. Es weist den Compiler lediglich an, eine Variable oder einen Ausdruck auf andere Weise zu betrachten.
Vor diesem Hintergrund können Sie nichts gewinnen, wenn Sie versuchen, eine Methode zu schreiben, die einen "variablen" Typ zurückgibt. Sie können auch schreiben Sie einfach
public Base get(int i){
return v.get(i);
}
Das Objekt, das es gibt ein Base
, Child1
, Child2
, etc sein könnte .; Es ist der gleiche Typ wie das Objekt, als Sie es in den Vektor eingefügt haben. Wenn Sie get
rufen, wenn Sie das Ergebnis erwarten ein Child1
zu sein, können Sie
Child1 child = (Child1)container.get(n);
sagen, welche eine Ausnahme auslösen, wenn das Objekt kein child1
ist. Oder Sie können instanceof
verwenden, um sie zu überprüfen:
Base child = container.get(n);
if (child instanceof Child1) {
...
}
Wenn dies nicht gut genug ist, müssen Sie deutlicher erklären, was Sie erreichen wollen und warum dies nicht funktionieren wird.
MEHR: Nach dem Bearbeiten lesen, das sagt, Sie wollen etwas tun:
JSONObject o;
//...
o.get("nestedObject").get("array").get(3);
Sie brauchen kein Casting, dies zu erreichen. Was Sie benötigen, ist ein abstrakter Basistyp JSONValue
, der jede Art von Wert darstellt, der von einem JSON-Parser zurückgegeben werden kann. Die Unterklassen sind Dinge wie "Objekt", "Array" und alle skalaren Typen, die Sie benötigen (Integer, String, etc.). get
würde JSONValue
zurückgeben. In Wirklichkeit gibt es ein Objekt eines anderen Typs zurück, aber der Compiler muss wissen, dass es JSONValue
zurückgibt.
Jetzt ein JSONValue
benötigen zwei get
Methoden, eine, die eine String
und man nimmt, die eine int
oder Integer
nimmt. Dies werden polymorphe Methoden sein. Sagen Sie v
ist ein JSONValue
und Sie sagen v.get("array")
: die Methode, die es tatsächlich aufruft, kann basierend auf dem tatsächlichen Typ von v
anders sein. Wenn also v
Ihr "Objekt" -Typ ist, ruft er die Methode auf, die Sie für den Objekttyp definiert haben; Wenn v
ein Integer-Typ ist, wird die für den Integer-Typ definierte Methode usw. aufgerufen. Was Sie wollen, ist für die get
Methode, die eine String
nach dem Feld für den JSON "Objekt" Typ sucht, und eine Ausnahme für alles andere auslösen. In ähnlicher Weise wird für die get
-Methode, die einen ganzzahligen Parameter verwendet, die Methode für den JSON- "Array" -Typ eine Liste oder etwas nachschlagen, und die Methode für jede andere Unterklasse von JSONValue
löst eine Ausnahme aus. Kein "Casting" ist dafür erforderlich. Casting ist ein Kompilierzeitkonzept. An allen Punkten weiß der Compiler nur, dass er mit einer JSONValue
arbeitet. Aber zur Laufzeit wird der tatsächliche Typ des Objekts verwendet, um zu bestimmen, welche Methode aufgerufen werden soll, sodass der Compiler nichts mehr wissen muss.
Dies ist ein Grundkonzept, das alle Java-Programmierer wissen müssen (auch Javascript, Python und so ziemlich jede andere Sprache heutzutage, obwohl Polymorphie in interpretierten Sprachen wie Javascript und Python anders gehandhabt wird). Das Tutorial https://docs.oracle.com/javase/tutorial/java/IandI/index.html deckt dieses und verwandte Konzepte ab. Es könnte auch bessere Java-Tutorials zum Thema "Polymorphismus" geben.
müssen Sie von container.get einen beliebigen Typ zurückgeben, der von der Basis ausgeht? – msoliman
Ja // 10 weitere Zeichen – saga
Wenn ich richtig verstanden habe, können Sie generische mit der Beschränkung von der Basis verwenden, ist das was du meinst? –
msoliman