Java - Superklassenvariablen in Unterklassen initialisieren?

7

Okay, sagen wir zum Beispiel, ich habe eine abstrakte Klasse namens "Vehicle". Die Fahrzeugklasse hat unter anderem eine statische Variable namens Räder, die nicht initialisiert wird. Was ich tun möchte, habe andere Unterklassen, die sich von der Fahrzeugklasse erstrecken, wie "Motorrad" und "Lastwagen", und in diesen Unterklassen werden die Räder initialisiert.

Code:

%Vor%

Aber das Folgende funktioniert nicht:

%Vor%

Gibt es eine Möglichkeit, dies effektiv zu tun?

BEARBEITEN: Danke an alle, die bisher geantwortet haben. Ich weiß, dass das Erstellen von Instanzen wahrscheinlich ein besserer Weg ist, als alle in separate Klassen zu schreiben, aber ich bekomme den "statischen" Teil von Java nicht perfekt, also brauche ich hier ein wenig Hilfe.

Was ich für mein Programm versuche, ist separate Sprites für die Motorrad- und Truck-Klassen, und ich möchte, dass sie statisch sind, so dass ich das Bild nicht jedes Mal neu laden muss, wenn ich eine Instanz von einem erzeuge Motorrad oder LKW. Abgesehen davon haben sie fast identische Eigenschaften, weshalb sie sich beide von der Vehikel-Superklasse erstrecken.

Der einzige andere Weg, wie ich das sehen kann, besteht darin, die Sprite-Variable nicht in der Klasse Fahrzeug zu deklarieren, sondern in der Klasse Motorcycle / Truck wie folgt:

%Vor%     
user1935527 28.12.2012, 22:46
quelle

7 Antworten

11

Wenn "Räder" statisch sind, gibt es nur eines und es gilt für alle Fahrzeuge gleichzeitig. Dreirad, ein Motorrad, ein 18-Wheeler-Truck und ein Ford werden alle die gleiche Anzahl von Rädern haben.

Das macht keinen Sinn für mich. Es wäre besser, "Räder" eine Instanzvariable zu haben, die in der Elternklasse ist, aber jede Unterklasse entsprechend setzt.

Aber Sie können versuchen

%Vor%

HINWEIS: Ich füge meine Antwort hinzu, da Sie Ihre Frage hinzugefügt haben.

Ich mag Ihre Idee, Statik in jeder der Unterklassen zu haben. Aber Sie sollten sie privat machen. Dann lege eine abstrakte Methode in die Elternklasse (Vehikel) wie

%Vor%

Dann muss jede direkte Unterklasse dieselbe Methode haben und die private statische Variable zurückgeben.

Machen Sie die Variable statisch, so dass Sie sie nur einmal laden müssen. Machen Sie sie privat, damit Code außerhalb der Klasse selbst nicht damit täuschen und Fehler einführen kann. Sie könnten sie, wenn möglich, "final" machen, damit der Code in der Klasse sie nicht nachträglich ändern und Bugs einführen kann. (Eine 'finale' Variable kann ihren Wert nicht ändern, aber der Inhalt ihres Wertes kann sich ändern. Also ist 'final' nicht so wunderbar, wie es sein könnte.)

    
Lee Meador 28.12.2012, 22:49
quelle
6

Was Sie versuchen zu tun, ist grundlegend fehlerhaft. Sie könnten Motorcycle initialisieren wheels einmal:

machen %Vor%

... oder jedes Mal, wenn eine Instanz erstellt wurde:

%Vor%

Aber es gibt nur eine Variable - nicht eine für Motorcycle , eine für Truck usw. Wenn Sie das Gleiche für Truck und Motorcycle getan haben, dann wird der Wert initialisiert zuletzt würde "gewinnen".

Es ist nicht klar, wie Sie dieses Feld trotzdem benutzen wollen - aber wenn Sie nur ein einzelnes statisches Feld haben, dann wird das nur einen einzelnen Wert haben - nicht einen pro Unterklasse.

    
Jon Skeet 28.12.2012 22:48
quelle
2

Statische Member werden nur einmal definiert und sind für jede Erweiterungsklasse gemeinsam. Wenn Sie den Wert in einem davon ändern, wirkt sich dies auf alle anderen aus. Dies ist, was ich glaube, dass Sie wirklich erreichen wollen:

%Vor%     
João Simões 28.12.2012 22:59
quelle
2

Ich denke, es gibt einen wesentlich eleganteren Weg, dies zu tun

Was ich vorschlage, leidet immer noch unter der Einschränkung, dass Sie eine Instanz benötigen. Ich sehe das nicht anders, weil wheels als Teil der Oberklasse verfügbar sein soll, aber der Wert von wheels hängt von der Unterklasse ab und innerhalb von Vehicle gibt es keine Vorstellung von einem Unterklasse-Typ ohne eine Instanz.

Meiner Meinung nach ist "Wheels" in diesem Fall weder eine statische noch eine nicht statische Eigenschaft. Es handelt sich um die Klasse Metadaten . Und die Java-Methode zur Angabe von Klassenmetadaten erfolgt über Annotationen.

Was Sie brauchen, ist eine benutzerdefinierte Annotation wie diese:

%Vor%

Dann notieren Sie Motorcyle wie folgt:

%Vor%

In der Oberklasse stellen Sie einen Zugriffsmechanismus bereit, der den Wert der Annotation-Eigenschaft abruft. Ich würde empfehlen, einen "lazy evaluation" -Ansatz zu verwenden, damit Sie die Reflektion nicht jedes Mal verwenden, wenn Sie den Wert benötigen.

Beachten Sie die Verwendung von this , um die Instanz zu erhalten:

%Vor%

Meiner Meinung nach ist dies die eleganteste Lösung.

    
DaBlick 25.09.2015 14:41
quelle
2

Die ursprüngliche Klassendeklaration:

%Vor%

funktioniert nicht, da die statische Variable mit der Klasse übereinstimmt, in der sie deklariert wurde. Statische Klassenvariablen erstellen Speicher für nur eine Instanz der Variablen pro Klasse und nicht pro Klassenobjekt. Wenn der Compiler (jvm) die statische Variable in der Klasse Vehicle sieht, weist er dieser Variablen Speicher zu und dieser Speicherplatz ist statisch (ändert sich nicht). Jede nachfolgende Verwendung der Vehicle-Klasse, unabhängig davon, ob sie als Objekt erweitert oder instanziiert wird, zeigt auf dieselbe Speicherposition für die statische Variable.

Um die statische Variable in den untergeordneten Klassen zu verwenden, müssen Sie sie in einer Methode verwenden. So könnten Sie im Prinzip Ihre Motorradklasse wie folgt neu schreiben:

%Vor%

und es wird kompilieren; Sie erhalten jedoch möglicherweise nicht die erwarteten Ergebnisse. Zum Beispiel, wenn Sie dies in Ihrem Code tun (vorausgesetzt, Truck-Klasse wird wie Motorcycle-Klasse deklariert und weist 4 Rädern zu und es gibt eine Getter-Methode, um den Wert von Rädern zurückzugeben).

%Vor%

wird gedruckt:

Motorrad hat 4 Räder.

    
alaniane 29.06.2016 18:27
quelle
0

Vielleicht möchten Sie über die Konstruktoren nachdenken, die Sie verwenden.

%Vor%

Das Motorrad verwendet den Superkonstruktor, der weiß, was mit dem Parameter zu tun ist. Es setzt automatisch Räder auf 2.

    
helsont 28.12.2012 22:53
quelle
0

Wenn Sie eine statische Variable in Ihren Objekten erstellen, wird diese für jede Fahrzeugklasse, die Sie erstellen, gleich sein, selbst wenn Sie eine andere Unterklasse für Ihre abstrakte Fahrzeugklasse erstellen würden. Dies wegen der "Natur" irgendeiner statischen Variable.

Ich denke, Sie möchten eine nicht statische Variable verwenden, so dass Sie für jede Instanz einer Unterklasse der abstrakten Fahrzeugklasse den Wert der Räder bestimmen können, und zwar wie folgt:

%Vor%

und jede Unterklasse:

%Vor%

Sie können dies auch für die statische Variable tun, aber dann ändern Sie sie für jede Instanz einer Unterklasse von Vehicle

Ich hoffe, ich habe dir geholfen

    
Funonly 28.12.2012 22:56
quelle