gpt4 book ai didi

java - ArrayList 和检索对象时的非特异性

转载 作者:行者123 更新时间:2023-12-03 05:03:24 25 4
gpt4 key购买 nike

首先对这个问题表示歉意 - 我是 Java 新手,只是想不出一个好的表达方式。

我有一个名为“Animal”的抽象类和一些继承自“Animal”的名为“Pig”、“Horse”等的特定类。

我正在使用 ArrayList 创建一个动物列表,这些动物是实例化的 pig 、马等。然后我想将动物从列表中删除并与它们一起工作,但是 Java 将只允许我与它们交互是基类 Animal。

这是我的主要代码的快速列表,应该可以使这一点更清楚:

import java.util.ArrayList;

public class Main {

public static void main(String[] args) {

ArrayList<Animal> animals = new ArrayList<Animal>();
animals.add(new Pig("Porkey", "pink"));
Animal animal = animals.get(0);
animal.introAnimal(animal);
animal.oink(); // Won't compile.Specific Pig class method
}
}

现在我知道我可以使用“Pig Animal = (Pig) Animals.get(0)”进行转换,但我的观点是我希望能够与这些动物一起工作,无论它们是什么如果我需要知道的话,可以稍后使用 getObjectType 或类似的内容。

这似乎几乎是多态性的障碍:)我不太担心这个特定的代码(我只是在练习),但更多的是这个问题的一般解决方案。

非常感谢。

最佳答案

您必须使用动物通用的术语。您可以指示动物说话(这可能是一个通用术语),而不是指示动物发出声音(这不适用于所有动物)。

Java 是一种静态类型语言,因此如果您尝试使用在运行时可能不起作用的方法,编译器会提示。它不是一种动态语言,不允许您调用任何方法以希望它可以在运行时工作。虽然这更灵活,但可靠地构建大型程序却更困难。例如假设我重命名一个方法,我怎么知道谁在调用该方法来重命名它。

abstract class Animal {
void speak();
}

class Pig extends Animal {
public void speak() {
System.out.println("Oink");
}
}

class Dog extends Animal {
public void speak() {
System.out.println("Woof");
}
}

class Duck extends Animal {
public void speak() {
System.out.println("Qwack");
}
}

List<Animal> animals = Arrays.<Animal>asList(new Dog(), new Pig(), new Duck);
for (Animal animal : animals)
animal.speak();

打印

Woof
Oink
Qwack

Thanks for your answer. The thing I was trying to get at is that I want to be able to create a list and then remove stuff from the list and be able to deal with the subclass depending on which subclass it is at run-time. I just didn't realise you could cast later on to get subclass methods.

有两种方法可以做到这一点。

List<Animal> animals = ...
for (Animal animal: animals)
if (animal instanceof Pig) {
((Pig) animal).oink();
}

这仍然需要你知道你想要一只 pig 。假设您有另一个类 Boar 并且它也有一个 oink 方法,并且您不关心 Pig 和 Boar 没有父类(尽管您可以)

List<Animal> animals = ...
for (Animal animal: animals) {
Method method = animal.getClass().getMethod("oink");
if (method != null)
method.invoke(animal);
}

现在假设该方法不仅不在 Animal 中,而且对于 Pig 来说是私有(private),因此更难调用。

List<Animal> animals = ...
for (Animal animal: animals) {
Method method = animal.getClass().getDeclaredMethod("oink");
if (method != null) {
method.setAccessible(true);
method.invoke(animal);
}
}

关于java - ArrayList 和检索对象时的非特异性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27886119/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com