Web Analytics Made Easy -
StatCounter Take any object - CodingForum

Announcement

Collapse
No announcement yet.

Take any object

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Take any object

    Hi all,
    As part of my program design one of my classes creates a new instance of a different class and then [needs to] store this new object into an ArrayList. However, this new object can be one of many different classes. As a result, if I want to add this object to the ArrayList, I can't because the ArrayList can only take one type of object. Is there anything else I can use, or is there a way to overcome this?

    I've tried the following type of code as an alternative:
    Class2 class3 = new Class3();
    Class2 class4 = new Class4();
    Class2 class5 = new Class5();
    However this does not work because Class2 is not of type Class1 etc.. I then thought that Class1 could hold an ArrayList of type Class2 and store these, but that doesn't seem to be working either. But I need to achieve something along these lines

    Here is how it (what I just explained) would look on an object diagram:
    Code:
              Class 1 (holds an ArrayList of type Class2)
                 |
                \|/
              Class2 (creates one of the other classes)
            /      |      \
          \/_     \|/     _\/
      Class3    Class4    Class5
    Thanks for any help

  • #2
    Post the relevant code so we can see where you are going wrong. A few questions:

    Does Class2 extend Class1?
    Do the rest of the classes extend Class2?

    There are a few ways that you can approach this, you can use Class2 as an abstract class, or use it as an interface and use generic's to build the type in your ArrayList etc.... Either way, lets see what you have so we know which direction to take.

    Comment


    • #3
      Below is the code from the class. This fits with my original post where I have provided a class diagram.

      This would be Class1 from the original post:
      Code:
      import java.util.*;
      public class Simulator {
          private ArrayList animals;
      
          public Simulator() {
              Animal animal = new Animal();
              animals.add(animal);
          }
          ...
      This would be Class2 from the original post:
      Code:
      import java.util.*;
      public class Animal {
          
          private double probability;
          private Animal animal;
          
          public Animal() {
              setProbability();
              if (probability <= 0.15) {
                  Animal animal = new Fox();
              }
              if (probability > 0.15 && probability <= 0.50) {
                  Animal animal = new Rabbit();
              }
          }
          
          public void setProbability() {
              Random number = new Random();
              probability = number.nextDouble();
          }
          ...
      This would be Class3 from the original post:
      Code:
      public class Rabbit {
          public Rabbit() {
          }
          ...
      This would be Class4 from the original post:
      Code:
      public class Fox {
          public Fox() {
          }
          ...
      Class2 doesn't extend Class1. It is important that Class1 is concrete as it performs many tasks throughout the program.
      None of the classes extend eachother.

      Thanks for the help

      Comment


      • #4
        You will need to make your individual animal classes extend the Animal class. If there is going to be common functionality between them, you could make it an abstract class, and put the common code in the Animal class and let the individual classes implement the instance-specific code.

        Comment


        • #5
          In the Simulator class, when I eventually take the Fox and Rabbit objects out of the Arraylist will I be able to call their methods along with the Animal class' methods?
          Last edited by webguy08; Apr 7, 2009, 08:42 PM.

          Comment


          • #6
            Yes, you may have to cast them to their individual classes, or define the methods you want in the abstract class.

            Comment


            • #7
              I have made the Animal class a super class, however I get an error in the Simulator class at the point which I have shown in the code below.

              Code:
              import java.util.*;
              public class Simulator {
                  
                  private int tick;
                  private int tickTime;
                  private ArrayList<Animal> animals;
                  
                  public Simulator() {
                      Animal animal = new Animal();
                      animals.add(animal); [COLOR="DarkRed"]// Null pointer exception[/COLOR]
                      }
              ...
              This relates to my original problem where I need to store objects of different types into an ArrayList, or something similar.

              Comment


              • #8
                You haven't created the ArrayList. You will need to create your ArrayList before using it:

                Code:
                animals = new ArrayList<Animal>();

                Comment


                • #9
                  Ugh I'm so stupid lol

                  Thanks for the help

                  Comment


                  • #10
                    I have come across an error
                    When the Simulator class calls the Animal class to create a new Animal (either a Fox or Rabbit) I get a StackOverflowError, and it highlights the constructor in the Animal class at the line: super();. From what I have read I have gathered that this is because the Animal class is calling the Fox/Rabbit class, and then the Fox/Rabbit class calls the constructor of the Animal class, thus it is an infinite loop. Is this correct? So now, I have hit a brick wall lol. Are there any solutions to this, or is this a dead end?

                    Comment


                    • #11
                      I think you're a bit confused here.

                      You should have the Fox and Rabbit classes as the children, while the Animal class is the parent.

                      So:
                      Code:
                      public Fox [COLOR="Red"]extends Animal[/COLOR]
                      {
                          public Fox()
                          {
                              [COLOR="Red"]super();[/COLOR] [COLOR="Green"]// Calls Animals constructor[/COLOR]
                          }
                      }
                      You would then instantiate your Fox object like so:
                      Code:
                      Fox myFox = new Fox();
                      You will not be instantiating the Animal class directly. Your Fox and Rabbit classes will do that using their super() directive.

                      -Shane

                      Comment


                      • #12
                        Oh, I forgot to mention that I updated the code from what is shown in the original post. The Simulator class is the same as the original post, the Animal class is a superclass of the Fox and Rabbit classes. What you have written is exactly how my Fox and Rabbit classes look like. The Simulator class calls the Animal class to create either a Fox or Rabbit, and then stores that Animal in its own ArrayList. The code is exactly the same as the original post except for the creation of the Animal superclass, and the Fox and Rabbit classes using 'extends'.

                        Sorry I didn't mention the new code

                        Comment


                        • #13
                          Your Animal class should not be instantiating Fox or Rabbit classes. A parent class should NEVER instantiate a child class. A parent object is usually more of a container object for which to build up your children classes, and generally has no knowledge of its children.

                          Your Simulator class should have an array list declared as so:
                          Code:
                          ArrayList<Animal> animalList = new ArrayList<Animal>();
                          Then the Simulator class should add your animals like so:
                          Code:
                          animalList.add(new Fox());
                          animalList.add(new Rabbit());
                          -OR-
                          Code:
                          Fox fox1 = new Fox();
                          Rabbit rabbit1 = new Rabbit();
                          animalList.add(fox1);
                          animalList.add(rabbit1);
                          This works because the Array List is expecting an Animal object, and since Fox and Rabbit are subclasses of Animal, it's allowed.

                          If you wanted to grab the Fox from the Array List, you would do something like:
                          Code:
                          Fox foxy = (Fox) animalList.get(0);
                          You're getting the Animal object from the first index of the list and casting him back to his original object name. If you don't do this, you won't have access to the variables and methods contained in Fox and could only use the variables and methods in Animal.

                          -Shane

                          Comment


                          • #14
                            Excellent post TheShaner! I fully understand that now

                            Comment

                            Working...
                            X