如果我有一个在运行时填充的Birds数组,我如何访问特定于子类的成员方法?
class Bird
{
public Bird() {}
public void fly(int x) {
System.out.println("Flew "+x+" meters");
}
}
class DumbBird extends Bird
{
public DumbBird() {super();}
public void fly(int x) {
x-=5; //we're dumb
System.out.println("Flew "+x+" meters");
}
public void sing() {
System.out.println("La la la!");
}
}
public static void main(String[] args)
{
Bird[] cage = new Bird[10];
cage[0] = new Bird();
cage[1] = new Dumbbird();
cage[2] = new Sleepybird();
//.... more bird types
cage[1].sing(); //is inaccessable because it is of type Bird not DumbBird!
}
有没有一种好的方法可以在访问特定于子类的成员函数的同时拥有一个泛型类型数组?我不想编辑Bird类。
理论上是的。放入数组中的项是可具体化的,因此您可以确定要查看的类型,并将特定对象强制转换为其实际类型。不过,这不是一个非常干净的解决方案,所以我不推荐它
您可以考虑使用一个表示bird的抽象类或接口,该类或接口具有大多数birds支持的方法,以及检查方法canSing()
或canFly()
。不支持这一点的鸟类,如不会飞的鸟类,如果你试图调用一种鸟类不支持的方法,可以抛出一个UnsupportedOperationException
,但没有简单的方法可以通用地引用所有的鸟类,并了解每个子类型的鸟类可以拥有的所有不同方法。
只是从评论中删除我的答案。
切换到使用列表而不是数组,当你拉出特定的鸟时,你需要将其转换为正确类型的"鸟",请参阅下面的代码示例:
import java.util.ArrayList;
class Bird
{
public void fly(int x) {
System.out.println("Flew "+x+" meters");
}
}
class DumbBird extends Bird
{
public void fly(int x) {
x-=5; //we're dumb
System.out.println("Flew "+x+" meters");
}
public void sing() {
System.out.println("La la la!");
}
}
class Test {
public static void main(String[] args) {
ArrayList<Bird> cage = new ArrayList<Bird>();
cage.add(new Bird());
cage.add(new DumbBird());
cage.add(new Bird());
cage.add(new DumbBird());
cage.add(new SleepyBird());
((DumbBird) cage.get(1)).sing();
}
}