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

ten*_*mes 2 java arraylist

首先为这个问题道歉 - 我是Java的新手,只是想不出一个好的方法来表达它.

我有一个名为"动物",有的叫"猪"特定的类抽象类,"马"等,从"动物"继承.

我使用一个ArrayList创建动物名单,这被实例化猪,马等.然后我想拉断的动物名单,并与他们合作,但那么Java将只允许我与他们进行互动,如果他们是基类,动物.

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

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   
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我知道我可以用" Pig animal = (Pig) animals.get(0)" 进行投射但是我的观点是我希望能够与这些动物一起工作而不管它们是什么,如果我需要知道的话,可以使用getObjectType或稍后的一些.

看起来好像这是多态性的障碍:)我不是太担心这个特定的代码(我只是在练习),但更多的是在这个问题的一般解决方案.

非常感谢.

Pet*_*rey 5

您必须使用动物通用的术语.oink您可以指示speak哪个动物可以是通用术语,而不是指示动物不适用于所有动物.

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();
Run Code Online (Sandbox Code Playgroud)

版画

Woof
Oink
Qwack
Run Code Online (Sandbox Code Playgroud)

感谢您的回答.我试图得到的是,我希望能够创建一个列表,然后从列表中删除东西,并能够处理子类,具体取决于它在运行时的子类.我只是没有意识到你可以稍后再去获取子类方法.

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

List<Animal> animals = ...
for (Animal animal: animals)
    if (animal instanceof Pig) {
        ((Pig) animal).oink();
    }
Run Code Online (Sandbox Code Playgroud)

这还需要你知道你想养猪.假设你有另一个类Boar,它也有一个oink方法,你不关心Pig和Boar没有父类(尽管你可以)

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

现在让我们说这个方法不仅没有,Animal而且privatePig让它更难调用.

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