只能从方法访问 Parent class 变量

Can only access Parent class variables from method

所以我 运行 关注的问题是这个。我编写了一个方法作为程序的一部分,我用它来显示 ArrayList 中的所有对象。这个 ArrayList 中存储了三种不同类型的对象:Fungus、Flowers 和 Weeds。我可以毫无问题地调用 plantList.get(i).getName()plantList.get(i).getColor 方法。这两个变量都属于名为 Plant 的父 class。但是,当调用下面的方法plantList.get(i).getPoison()(这个方法属于subclass Fungus)时,我得到一个编译器错误,说它找不到变量Fungus.

我已经尝试将其与子class 独有的所有其他变量一起使用,同样的事情发生了。所以我可以从父 class 'Plant' 访问变量,但不能从 'Fungus' 'Flower' 或 'Weed' 的任何子 class 访问变量。我刚开始使用 subclasses 和 superclasses,所以我很难弄清楚问题出在哪里。

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());
        }
    }
}

Java 是 strongly typed language. That means that, if you want to use methods of child class you have to cast down 到 child class.

在你的例子中:

...
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
}
...

您使用 constains 进行的检查无效。要检查 object 的类型,您需要使用运算符 instanceof.

一个好的解决方案是使用动态调度。 IE。让元素自己决定要打印什么信息。

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());
    }
}

您的循环将如下所示:

public static void displayPlant(ArrayList<Plant> plantList) {
    for(Plant p : plantList)
        System.out.println(p); // This calls toString
}

其实你做错了,

一旦将子 class 的对象保存到父 class 变量中,那么在编译时它只搜索或查找在父 class 中声明的方法和变量。

如果你想访问子 class 变量,那么你需要先找出子 class,然后根据

对其进行类型转换
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
        }
    }

希望对您有所帮助。谢谢