简体   繁体   中英

Proper way of creating an array of Objects holding objects from superclass and subclass

The problem is on my second switch case 1: I will put the "arrayEmployees[0]." but it doesn't see my methods in the superclass PersonData or the subclass personLocation. My understanding of polymorhpism is a bit shady as well as the internal "Object" possibility as I just began learning about these so perhaps I am referencing them wrong.

I was given these instructions:

Design a new class called PersonTest with a main method that defines a PersonData object and a PersonLocation object (both without arguments) and two more objects with arguments and store all the objects in an Array for retrieval and modification of instantiated objects (ie Array of Objects).

My Actual Code

package lab5;
import java.util.InputMismatchException;
import java.util.Scanner;

public class PersonTest 
{
    public static void main(String args[])
    {
        Scanner input = new Scanner(System.in);

        PersonLocation personLocation = new PersonLocation();
        PersonData personData = new PersonData();

        PersonLocation personLocationOverLoaded = new PersonLocation("Hamilton");
        PersonData personDataOverloaded = new PersonData("Stirling", "905-567-7656");

        Object[] arrayEmployees = new Object[4];
        arrayEmployees[0] = personLocation;
        arrayEmployees[1] = personLocationOverLoaded;
        arrayEmployees[2] = personData;
        arrayEmployees[3] = personDataOverloaded;

        int user = 0;
        int menu = 0;

        // Get input here, put into variable "user"

        switch(user)
        {
            case 1:
                System.out.print("Printing Object Information With Given Values\n\n\t");

                arrayEmployees[0]. //Issue
        }
    }//End Main Method
}//End Class PersonTest

What is Supposed to Happen: I am suppose to be able to reference from my array as shown above (arrayEmployees[0].) and have my methods show up for that particular class.

Object[] arrayEmployees = new Object[4];
arrayEmployees[0] = personLocation;
arrayEmployees[1] = personLocationOverLoaded;
arrayEmployees[2] = personData;
arrayEmployees[3] = personDataOverloaded;

This did exactly what you wanted to do, actually. This is an array that contains objects of both a given type and its superclass.

However, by doing so, you lose some information, as you noticed.

When you create an Object[] , you are telling the compiler that "This is an array of Object s". Thus, when you go to retrieve an element of this array, all the compiler knows is that "This array contains Object s". It does not know that the first two elements are PersonLocation instances, and does not know that the last two elements are personData elements. It just knows that the array contains Object s.


This is a fundamental limitation of how collections in Java work in general. Collections in Java have one "overall" type, as in you'll always have a " Collection of Number s", "array of PersonData s", " ArrayList of String s", etc., and not " Collection of Integer s and Double s`" So no matter the actual type of whatever's inside, all the compiler knows that the type of the object you'll get out of the collection is the type of that collection.

For example, say I have List<Number> list = new ArrayList<Number>(); . All the compiler knows is that the contents are Number s. It doesn't know if the first element is an Integer , Double , Long , etc. It's just a Number . And because of that, you can't use a Long -specific method like list.get(0).longValue() , because the compiler can't guarantee that the first element is an Integer . It just knows that list.get(0) returns a Number , and that Number s don't have a longValue() method.


So how do you solve this?

You have a few options.

  1. Use the instanceof operator to test arrayEmployees[0] for its actual type, then cast as needed and perform desired methods. This is more awkward, but if you must have a single array, you really don't have much of a choice.
  2. Use a separate array for each class, so no information is lost.

Given the assignment you need to do, it seems that multiple arrays aren't an option, as the instructions specify a single array, so you might need to do the test and cast. Here's the general idea:

<variable> instanceof <type>

tests for whether variable is-a <type> . For example:

arrayEmployees[0] instanceof PersonLocation

tests to see if arrayEmployees[0] is a PersonLocation .

This test returns a boolean , so you can use that as the condition for an if statement. Inside that if statement, you can downcast arrayEmployees[0] into a temporary reference:

if (arrayEmployees[0] instanceof PersonLocation) {
    PersonLocation temp = (PersonLocation) arrayEmployees[0];
    // execute whatever you need on temp
}

Just be warned -- instanceOf will also match subclasses. So both x instanceof Integer and x instanceof Number will both return true if x is declared as Integer x = 1; .


Hopefully that's enough to get you started. Feel free to ask any questions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM