1

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 (i.e. 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.

  • What was wrong with the answer to your [previous question](https://stackoverflow.com/questions/24297404/storing-objects-in-an-array-for-retirevel-and-modification-of-instantiated-objec)? Did it not explain something? If you tried something and it didn't work, please expand on exactly what you tried and exactly what went wrong. – awksp Jun 19 '14 at 04:36
  • My previous question made the arrays but it did not work with the superclass and subclass, because both classes have a default constructor as well as an overloaded constructor. So I have to make the objects as shown above I believe. – user3754645 Jun 19 '14 at 04:39
  • Can you expand on "did not work with the superclass and subclass"? Show *exactly* what you tried, and describe specifically what went wrong. From what I can read the previous answer *should* have worked. – awksp Jun 19 '14 at 04:40
  • I added my class I created, the problem is on my second switch case 1: I will put the "arrayEmployees[0]." but it doesnt see my methods in the superclass PersonData or the subclass personLocation – user3754645 Jun 19 '14 at 04:46
  • What *exactly* is the problem? The more detail you provide, the more likely you are to get a favorable response from readers. You're getting there. – awksp Jun 19 '14 at 04:48
  • Thank you for your patience, very new to this site. Was that last comment better? – user3754645 Jun 19 '14 at 04:49
  • That's better. It's a better idea to put that information in your question, where it's more visible. – awksp Jun 19 '14 at 04:50
  • Your Basic concepts are not clear `ArrayList people = new ArrayList(4); people.add personLocation;` Your adding PersonLocation Type object in an ArrayList that stores Strings only. Also I don't undertand what you are trying to ask. Please go through ur basics. – Oliver Jun 19 '14 at 05:01
  • Just a note; I think that there is quite a bit of fluff in this question. I'm going to leave it as is, as I'm not too sure about how to cut down, but as the main question is a sentence or two at the bottom of the question you might want to consider removing things so it's not as hidden. – awksp Jun 19 '14 at 05:02
  • Alright, thanks for you insight. – user3754645 Jun 19 '14 at 05:03
  • In addition, if you can you probably want to brush up on some of these concepts with your professor/TA, as someone explaining things to you in person is likely more helpful than someone explaining through text on the internet. – awksp Jun 19 '14 at 05:06
  • Sorry I know your done with this but was wondering my question is more to what is expected now. I cleaned it up and took out the "fluff". – user3754645 Jun 19 '14 at 05:06
  • It's better, but still needs some improvement. About half of the code you provided is unneeded; everything from `ArrayList people = new ArrayList(4);` and down could actually go. In addition, you should explain more clearly after your code what you expected to happen. It's stated up top, but you should expand more on *why* you thought it was that way. And don't worry, I'm working on an answer. – awksp Jun 19 '14 at 05:08
  • Do you know about casting and the `instanceof` operator? – awksp Jun 19 '14 at 05:23
  • I read about it but I do not fully understand. I am reading http://stackoverflow.com/questions/5289393/casting-variables-in-java right now. – user3754645 Jun 19 '14 at 05:26
  • I included a portion about it in my answer. Good to hear that you are looking around on your own! – awksp Jun 19 '14 at 05:27

1 Answers1

0
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 Objects". Thus, when you go to retrieve an element of this array, all the compiler knows is that "This array contains Objects". 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 Objects.


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 Numbers", "array of PersonDatas", "ArrayList of Strings", etc., and not "Collection of Integers and Doubles`" 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 Numbers. 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 Numbers 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.

awksp
  • 11,764
  • 4
  • 37
  • 44
  • I dont understand what you mean - 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; Also this will sound dumb but I don't see the importance of a superclass and subclass here. – user3754645 Jun 19 '14 at 05:35
  • Also thank you, I believe that instance of if statement will deffinitly help me in the right direction. :) – user3754645 Jun 19 '14 at 05:37
  • @user3754645 Say you have `Dog` as a superclass and `Poodle` as a subclass. If you declare `Dog d`, then `d instanceof Dog` and `d instanceof Poodle` will return `true` and `false`, respectively. However, if you declare `Poodle p`, `p instanceof Dog` and `d instanceof Poodle` will *both* return `true`. So if you're testing an array that has superclass objects and subclass objects, test for the more specific (i.e. subclass) objects first. In this example, test to see if an object is a `Poodle` before it is a `Dog`, because if you test for `Dog`s first you'll never test for `Poodle`s. – awksp Jun 19 '14 at 05:39
  • @user3754645 I mentioned superclasses and subclasses because you mentioned that the array would hold both of those. The order of `instanceof` testing is important, so I thought the mention would be helpful. And glad to hear that this helped! – awksp Jun 19 '14 at 05:40
  • Very helpful I appreciate it, I also appreciate that you didn't down grade my question lol I will probably be reading this over many times over the next few days, trying to learn this with good understanding in an hour is killing my brain xD – user3754645 Jun 19 '14 at 05:44
  • So this checked and added it to arrayEmployeees Correct? PersonLocation temp = (PersonLocation) arrayEmployees[0]; Now I call arrayEmployees.method? No that doesn't seem right – user3754645 Jun 19 '14 at 05:45
  • Oh ok so it is storing it in temp and temp.method seems to work. so that line is instantiating a new object called temp? Which is really an instance of arrayEmployee[0]? O.o – user3754645 Jun 19 '14 at 05:48
  • The fact that you were willing to take the time to improve your question greatly helped. To be frank, it isn't one of those thousands-of-upvotes questions like [this](https://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array), but it 1. states a problem, 2. gives an example, and 3. states what you were expecting. It might be a bit lean on showing research, but hey, there's always room to improve, and from the comments up there it seems you were doing that anyways. It's a decent question. – awksp Jun 19 '14 at 05:49
  • Yep, you figured it out. No, it isn't instantiating a new object. It's just creating a new *reference* to the same object that `arrayEmployee[0]` is pointing to. Because you declared the reference to be a reference to a `PersonLocation` object, the compiler allows you to call methods from `PersonLocation` on `temp`. – awksp Jun 19 '14 at 05:51
  • Trying my best too. You gave a lot of good pointers both with how to set the questions up as well as solving my issue and helping my understanding of polymorhpism. I greatly appreciated it. Alright a refernce to it excellent. – user3754645 Jun 19 '14 at 05:53
  • By the way a little off topic but how do you find questions to answer? – user3754645 Jun 19 '14 at 05:55
  • @user3754645 No problem. Seemed that you were trying to ask a good question but weren't quite there, so I thought I'd help. Glad to see it turned out well. Just a tip -- the general idea is that SO should be the *last* place to look. If you can, ask your TAs/prof, if they are available. Not everyone likes taking the time to explain what could be considered basics to a learning programmer. – awksp Jun 19 '14 at 05:57
  • Alright that's good to keep in mind. Only thing I can do to kinda make it even for your help is a song that is pretty awesome. Lindsey Stirling - Roundtable Rival. Newer artist but pretty catchy. It's dubstep mixed with alot of violin. I'm going to get back to finishing my work. Thanks alot. – user3754645 Jun 19 '14 at 05:58
  • @user3754645 I just monitor the newest stream for the Java tag and look for something that seems like I'd be familiar with. Then I open the question, decide what to do, etc. Might take some hanging around before you get started, but you'll learn enough eventually that you'll be able to help someone. – awksp Jun 19 '14 at 05:59
  • @user3754645 Thanks for the recommendation, I'll be sure to check that out. I'm a classical fan, but hey, a change of pace might be nice... – awksp Jun 19 '14 at 06:00