I know there are many questions similar to mine already but I still haven't found a solution that applies to my problem. I am required to use three different classes for this and to give you an idea, here is what some of my code looks like (included only those that I think are relevant):
public class Main {
//this is where I instantiate
public static void main(String[] args){
Habitat habitat1 = new Habitat( Habitat.habitatNumber, "Savanna", "Mixed woodland-grassland");
Habitat habitat2 = new Habitat(same arguments/parameters here);
Animal type1 = new Animal(1, "Tiger", "Carnivore", habitat1);
Animal type2 = new Animal(2, "Elephant", "Herbivore", habitat1);
Animal type3 = new Animal(3, "Horse", "Herbivore", habitat2);
Animal type4 = new Animal(4, "Cow", "Herbivore", habitat2);
habitat1.viewList(); //this will print the output mentioned below
}
}
public class Habitat {
//other attributes here
Animal[] animals;
public Habitat(int count, String name, String description) {
this.count = count;
this.name = name;
this.description = description;
//here I want to be able to reference/assign **Animal type1 and type2 to habitat1** and **Animal type3 and type4 to habitat2**
}
void viewList(){
//this method is for printing data/information about the habitats
}
public class Animal {
//other attributes here
Habitat habitat;
public Animal(int num, String name, String diet, Habitat habitat){
this.num = num;
this.name = name;
this.diet = diet;
this.habitat = habitat;
}
I know that in order to have an array of object animals, I need to write something like this:
Animal[] animals = new Animal[4];
animals[0] = type1;
animals[1] = type2;
animals[2] = type3;
animals[3] = type4;
The problem is that I cannot put this block of code in class Habitat because it cannot access type1-type4. When I put this in class Main, I am unable to reference it in class Habitat. Sorry if this is vague/unclear, I am still new at Java, especially abstraction.
There is more to this program as I will be printing many information but basically, the specific output I want in this particular problem is that when I print the contents of habitat1 for example, it will look something like this:
Habitat 1
Name: Savanna
Description: Mixed woodland-grassland
List of Animals:
Type 1
Name: Tiger
Diet: Carnivore
Type 2
Name: Elephant
Diet: Herbivore
CodePudding user response:
Provide method(s) on Habitat
for associating the Animal[]
.
For instance, if you define a constructor that accepts the Animal[]
then you can build that array first and then pass it into the constructor. You can also provide a setter that allows you to swap to a different Animal[]
at any point.
public class Habitat {
private Animal[] animals; // note that this should be private
public Habitat(Animal[] animals) {
this.animals = animals;
}
public void setAnimals(Animal[] animals) {
this.animals = animals;
}
}
This allows the main method to pre-generate the Animals or assign them later as needed.
public class Main {
public static void main(String[] args) {
Animal[] animals = ... build the array
Habitat habitat1 = new Habitat(animals);
Habitat habitat2 = new Habitat();
Animal[] moreAnimals = ... build another array of Animals
habitat2.setAnimals(moreAnimals);
}
}
CodePudding user response:
Add a method addAnimal( Animal animal )
to Habitat
and call this from the constructor of Animal
like this
…
habitat.addAnimal( this );
…
Of course this assumes that the fourth argument of the Animal
constructor is named habitat
.
And the animals
attribute should not be an array, but an instance of java.util.List
(preferrably a java.util.ArrayList
). Then the new method would look like this:
public final void addAnimal( final Animal animal )
{
animals.add( animal );
}
Perhaps you have to add some checks (not-null, for example), and when you want to make sure that an animal can be added just once, you should consider to use java.util.Set
instead of a List
(But this would mean some changes to the Animal
class as well).
If you really insist on an array for the attribute, the addAnimal()
method would get a bit more complex:
public final void addAnimal( final Animal animal )
{
if( animals == null )
{
animals = new Animals [1];
animals [0] = animal;
}
else
{
var curLen = animals.length;
var newAnimals = new Animal [curLen 1];
System.arraycopy( animals, 0 newAnimals, 0, curLen )
animals = newAnimals;
animals [curLen] = animal;
}
}
or
public final void addAnimal( final Animal animal )
{
if( animals == null )
{
animals = new Animals [1];
animals [0] = animal;
}
else
{
var curLen = animals.length;
animals = Arrays.copyOf( animals, curLen 1 );
animals [curLen] = animal;
}
}
Still error handling is missing.