Reputation: 340
So the issue I'm running into is this. I've written a method as a part of a program that I'm using to display all the objects in an ArrayList. There are three different types of objects stored in this ArrayList: Fungus, Flowers and Weeds. I'm able to call plantList.get(i).getName()
and plantList.get(i).getColor
methods with no issue. Both of these variables belong to the parent class called Plant. However, when calling the following method plantList.get(i).getPoison()
(this method belongs to the subclass Fungus) I get a compiler error saying that it cannot find the variable Fungus.
I've tried it with every other variable unique to a subclass, and the same things happens. So I can access variables from the parent class 'Plant' but not from any of the subclasses of 'Fungus' 'Flower' or 'Weed'. I'm new to using subclasses and superclasses so I'm having a hard time figuring out exactly where the issue is arising.
public static void displayPlant(ArrayList<Plant> plantList) {
for (int i = 0; i < plantList.size(); i++) {
System.out.print(plantList.get(i).getName());
System.out.print(plantList.get(i).getID());
System.out.print(plantList.get(i).getColor());
if (plantList.get(i).contains(Fungus) == true) {
System.out.print(plantList.get(i).getPoison());
}
else if (plantList.get(i).contains(Flower) == true) {
System.out.print(plantList.get(i).getSmell());
System.out.print(plantList.get(i).getThorns());
}
else {
System.out.print(plantList.get(i).getPoison());
System.out.print(plantList.get(i).getEdible());
System.out.print(plantList.get(i).getMedicinal());
}
}
}
Upvotes: 2
Views: 953
Reputation: 22595
Java is strongly typed language. That means that, if you want to use methods of child class you have to cast down to child class.
In your example:
...
else if (plantList.get(i) instanceof Fungus) { //check if plant is fungus
System.out.print(plantList.get(i).getSmell());
System.out.print(((Fungus)plantList.get(i)).getThorns()); //downcasting
}
...
Your check using constains
wouldn't work. To check type of object you need to use operator instanceof
.
Upvotes: 0
Reputation: 1549
Actually you are doing it in a wrong way,
Once you keep the object of child class into parent class variable then at compile time it search or find only the methods and variables that are declared in the parent class.
if you want to access the child class variables then you need to first find out the child class and then typecast it according
public static void displayPlant(ArrayList<Plant> plantList) {
for (int i = 0; i < plantList.size(); i++) {
Plant plant=plantList.get(i);
if (plant instanceof Flowers) {
Flowers fl=(Flowers)plant;
//TODO do whatever you want to do
}
else if(plant instanceof Weeds) {
Weeds wd=(Weeds)plant;
//TODO do whatever you want to do
}else if (plant instanceof Fungus) {
Fungus wd=(Fungus)plant;
//TODO do whatever you want to do
}
}
I hope it help you out. Thanks
Upvotes: 1
Reputation: 33865
A good solution is to use dynamic dispatch. I.e. let the element itself decide what information it wants to print.
class Plant {
...
public String toString() {
return String.join(" ", getName(), getID(), getColor());
}
}
class Fungus extends Plant {
...
@Override
public String toString() {
return String.join(" ", super.toString(), getPoison());
}
}
class Flower extends Plant {
...
@Override
public String toString() {
return String.join(" ", super.toString(), getSmell(), getThorns());
}
}
class Weed extends Plant {
...
@Override
public String toString() {
return String.join(" ", super.toString(), getPoison(), getEdible(), getMedicinal());
}
}
Your loop will look like this:
public static void displayPlant(ArrayList<Plant> plantList) {
for(Plant p : plantList)
System.out.println(p); // This calls toString
}
Upvotes: 2