Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you have an array of different kinds of objects?

I know that you can only have an array of a certain type (e.g. String, int, Student, etc.). I was wondering if this held true in the case of inheritance - i.e. whether or not a Bicycle object that extends Vehicle could be placed in a Vehicle array along with something else, like a Bus object.

Here's my 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.
        }
    }

}

Note that this is in the Java language

like image 677
Daniel Soutar Avatar asked Dec 08 '14 16:12

Daniel Soutar


3 Answers

You have an array of a super type.

for iterates through ALL items in an iterable object (here array).

Since there can be Bicycle or Bus instances (or even other types, which are currently unknown) in the array, you cannot treat it as a Bus Array.

What you probably want is this :

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

}

There is no good other way around this except for the visitor pattern maybe.

like image 193
Terry Storm Avatar answered Sep 30 '22 03:09

Terry Storm


If ClassTwo extends ClassOne and you make an array of ClassOnes, then you can add objects of ClassTwo to the array, however, you may only access members of ClassOne unless you cast.

like image 39
Ehdrian Avatar answered Sep 30 '22 03:09

Ehdrian


Took me some time to get your point.

If you want to do something like this, you'll have to cast the Vehicle into a Bus. However usually you should have an interface common to all vehicles.

As issueTicket() does not apply to bicycles you could probably think about not using the same interface for busses and bicycles at all.

Another idea would be to implement the issueTicket() method for bicecles just signalling an error as soon as it's called:

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

However in my opinion this still feels like a design which could be better.

For me to provide some more suggestions it would be good to know the reason why those objects shall be stored within the same container.

Hope that helps.

Best regards, Joerg

like image 31
Joerg S Avatar answered Sep 30 '22 04:09

Joerg S