2014-12-08 6 views
5

Ich weiß, dass Sie nur ein Array eines bestimmten Typs (z. B. String, Int, Student, etc.) haben können. Ich habe mich gefragt, ob dies im Fall der Vererbung gilt - d. H., Ob ein Fahrradobjekt, das das Fahrzeug ausdehnt, in einem Fahrzeugfeld zusammen mit etwas anderem wie einem Busobjekt platziert werden kann oder nicht.Können Sie eine Reihe von verschiedenen Arten von Objekten haben?

Hier ist mein Code:

public class Test{ 
    public static void main(String[] args) { 

     Bus bus1 = new Bus(); 
     Bicycle bike1 = new Bicycle(); 
     bike1.changeGear(true); 
     Bus bus2 = new Bus(); 
     Vehicle[] myFleet = {bus1, bike1, bus2}; // Note that Vehicle is an abstract class 
     for (Bus v: myFleet){ // Trying to access every bus in the Vehicle array. I already 
      v.issueTicket(1.50); // tried to get the computer to treat myFleet as a Bus array - doesn't 
      System.out.println(v); // work, sadly. 
     } 
    } 

} 

Beachten Sie, dass dies in der Sprache Java ist

+1

Was bedeutet 'nicht '? – helpermethod

+0

Das bedeutet, dass eine ClassCastException ausgelöst wird. Sagt, dass es nicht von Fahrzeug zu Bus werfen kann. –

Antwort

4

Sie haben ein Array von einem Super-Typ.

for durchläuft ALLE Elemente in einem iterierbaren Objekt (hier Array).

Da kann Bicycle oder Bus Instanzen (oder auch andere Arten, die derzeit nicht bekannt sind) werden in dem Array, können Sie behandeln es nicht als Bus Array.

Was möchten Sie wahrscheinlich ist dies:

for (Vehicle v : myFleet) { 
    if (v instanceof Bus) { 
     Bus b = (Bus)v; 
     b.doSomeSpecialThingsForABus(); 
    } 

} 

Es gibt keine gute andere Möglichkeit, um dieses mit Ausnahme der visitor pattern vielleicht.

+0

Gute Erklärung! Danke, das macht Sinn! –

0

Sie

verwenden können

java.lang.Object[] myFleet;

Aber das zu generisch sein könnte.

Wenn Ihre Objekte eine gemeinsame Schnittstelle haben (sagen wir Foo) dann könnte man

Foo[] myFleet;

haben Verwenden Sie auch einen Blick auf einige Java-Container wie ArrayList.

1

Wenn ClassTwo ClassOne erweitert und Sie ein Array von ClassOnes erstellen, können Sie Objekte des Typs ClassTwo zum Array hinzufügen. Sie können jedoch nur auf Mitglieder von ClassOne zugreifen, wenn Sie einen Cast durchführen.

+0

Klarstellung: "Mitglieder" bedeutet in diesem Zusammenhang Methoden, Felder usw. –

+0

Okay, wie wird man gegossen? Ich kann nicht scheinen, dass die Syntax funktioniert. Was du sagst, macht jedoch Sinn. –

+0

Hier ist eine kurze Anleitung: https://howtoprogramwithjava.com/java-cast/ – Ehdrian

0

Ja ... aber

Ja, können Sie eine Reihe von Fahrzeugen, zB Bus1, Bus2 und Bike1 haben.

... Aber das hält nicht an, dass Ihr Fahrrad ein Fahrrad ist, oder machen Sie es in einen Bus. Ein Array ist eine Liste von Verweisen auf Objekte, es nimmt keine neue Kopie des Objekts und wandelt es in den Typ des Arrays um: Die Objekte sind immer noch Instanzen ihrer ursprünglichen Klasse

Das Array kann halten Fahrzeuge unabhängig von ihrer Unterklasse, es ändert sie nicht in Busse, Fahrräder oder Fahrzeuge: der Typ bleibt gleich.

Sie können jedoch versuchen, ein Fahrrad als Bus zu nutzen: Wenn Sie akzeptieren, dass Sie alle Nicht-Bus-Attribute verlieren.Sie können auch instanceof entscheiden verwenden, wenn das Fahrzeug ein Bus schon, oder ein Fahrrad, und Umwandlung Sachen zu tun, wenn

erforderlich

dh

for (Vehicle v: myFleet){ // For each vehicle in the fleet 
    Bus b = (Bus) v; // Turn the vehicle into a bus 
    b.issueTicket(1.50); 
    System.out.println(b); 
} 
1

hast mir einige Zeit, um Ihren Punkt.

Wenn Sie so etwas tun möchten, müssen Sie die Vehicle in eine Bus umwandeln. Normalerweise sollte jedoch eine Schnittstelle für alle Fahrzeuge vorhanden sein.

Da sich issueTicket() nicht auf Fahrräder bezieht, könnte man wahrscheinlich daran denken, nicht die gleiche Schnittstelle für Busse und Fahrräder zu verwenden.

Eine weitere Idee wäre, die issueTicket() Methode für bicecles einen Fehler nur zu implementieren signalisiert, sobald es heißt:

Vehicle[] myFleet = {bus1, bike1, bus2}; // Note that Vehicle is an abstract class 
for (Vehicle v: myFleet){ 
    v.issueTicket(1.50); 
    System.out.println(v); 
} 

jedoch meiner Meinung nach der fühlt sich immer noch wie ein Design, das besser sein könnte.

Um weitere Vorschläge zu machen, wäre es gut zu wissen, warum diese Objekte im selben Container gespeichert werden sollen.

Hoffe, dass hilft.

Mit freundlichen Grüßen, Joerg

0

vorausgesetzt, dass Bus und Fahrrad beide entweder die gleiche Superklasse erweitern oder die gleiche Schnittstelle implementieren sie in eine Anordnung von der Art der entweder in der Schnittstelle oder der übergeordneten Klasse angeordnet werden kann.

Die zugreifen Sie überprüfen können, ob sie Instanzen von einem der Unterklassen sind

for (Vehicle v: myFleet){ 
    if(v instanceof Bus){ 
     ((Bus) v).issueTicket(1.50); 
    } 
} 

jedoch mit instanceof nicht empfohlen wird und in den meisten Fällen ist es besser, entweder eine Schnittstelle oder übergeordnete Klasse zu finden, die die allgemeinen beschreibt Funktionalität für alle Objekte im Array erforderlich.