Java:从arraylist中的对象访问子类方法
我正在尝试从arraylist访问类Car中的方法。类层次结构基本上是:Java:从arraylist中的对象访问子类方法,java,oop,arraylist,Java,Oop,Arraylist,我正在尝试从arraylist访问类Car中的方法。类层次结构基本上是: class车辆{} 汽车类扩展车辆{} 雪佛兰级扩展车{} 福特汽车{}级 在本例中,Car类有一个名为getID() main方法如下所示: Ford vehicle1=新福特(id、型号等); 雪佛兰车辆2=新雪佛兰(id、型号等); ArrayList=新建ArrayList(); 列表。添加(车辆1); 列表。添加(车辆2); 通过多次尝试,我可以访问getID()方法,如下所示: System.out.pri
class车辆{}
汽车类扩展车辆{}
雪佛兰级扩展车{}
福特汽车{}级
在本例中,Car
类有一个名为getID()
main
方法如下所示:
Ford vehicle1=新福特(id、型号等);
雪佛兰车辆2=新雪佛兰(id、型号等);
ArrayList=新建ArrayList();
列表。添加(车辆1);
列表。添加(车辆2);
通过多次尝试,我可以访问getID()方法,如下所示:
System.out.println(“车辆ID:”+((雪佛兰)列表.get(1)).getID();
哪个有效。。。我简直无法想象我是怎么做的。有更好的方法访问这些子类方法吗?对于一个严肃的程序,您的
Vechicle
接口应该定义所有车辆通用的所有行为方法,其中应该包括您的getID()
方法。但是,在某些情况下,您可能希望有只适用于特定类型车辆的特定方法;然后,您需要在车辆的子类或子接口中执行此操作。以上面的示例为例,您可能希望使用getID()
方法创建一个NamedVehicle
。如何安排接口和类取决于您。如果有帮助,请参阅桥梁设计模式
如上所述,在非常偶然的地方,你确实想做明确的演员 在列表中添加一个子类对象似乎很好,但在遍历列表时,您永远不知道将访问哪个子对象
我建议您可以通过以下方式将父引用点设置为子对象
Car vehicle1 = new Ford(id, model, etc);
Car vehicle2 = new Chevy(id, model, etc);
然后添加到列表中,如图所示。
当您迭代列表时,u将根据instanceof check向下转换它,这将使它更加常规
例:
Car c = (Car)list.get(0)).getID();
if(c instanceof Ford){
Ford f = (Ford)c;
System.out.println(f.getId());
}
为什么vehicle不是一个接口(类不能扩展接口,它们实现了接口)
据我所知,Vehicle
没有getId()
,而Car
有,这就是为什么不将Vehicle
数组列表对象强制转换为具有此类方法的子类(如Chevy
)会导致错误的原因
如果您这样做了:
System.out.println("Vehicle ID: " + ((Car) list.get(1)).getID());
这会奏效的
我建议您制作车辆
界面:
interface Vehicle{
public int getId();
}
class Car implements Vehicle{ //altough I think this also should be abstract
int id;
@Override
public int getId(){
return id;
}
}
使用此配置,您可以执行以下操作:
Car vehicle1 = new Ford(id, model, etc);
Car vehicle2 = new Chevy(id, model, etc);
ArrayList<Vehicle> list = new ArrayList<Vehicle>();
list.add(vehicle1);
list.add(vehicle2);
System.out.println("Vehicle ID: " + list.get(1).getID()); //Chevy ID
Car vehicle1=新福特(id、型号等);
汽车2=新雪佛兰(id、型号等);
ArrayList=新建ArrayList();
列表。添加(车辆1);
列表。添加(车辆2);
System.out.println(“车辆ID:+list.get(1.getID())//雪佛兰ID
由于getId()
方法是在Car
类中声明的,因此您只能通过继承来访问此方法(的cource需要用访问修饰符protected
或public
标记)
因此,Car
的任何子类都可以访问getId()
方法,并且应该在Car\getId
中标记行为,除非该方法在相关子类型中被覆盖,因此在运行时,将基于当前对象类型而不是对象引用来评估方法行为
现在来看一个最著名的OO(面向对象)特性,它是多态性(许多形式),它允许您在需要汽车的地方传递任何Car
子类型,并在需要Car
实例时返回任何Car
子类型
总而言之,你可以在汽车的数组列表中有任何汽车子类型:福特,雪佛兰,然后你就可以在列表的任何项上调用任何汽车实例方法(不管它是什么真正的类型,因为它是汽车)
现在的主要问题是,所描述的行为无法进入另一侧,因此父引用(在您的情况下车辆
)永远不会知道其后代的行为(在您的情况下汽车
),除非在道路下满足明确的强制转换
然后,您只需将Car
作为泛型类型来实例化您的数组列表(这就是您所说的
,
)即可:
publicstaticvoidmain(字符串[]args)
{
福特汽车1=新福特(id、型号等);
雪佛兰车辆2=新雪佛兰(id、型号等);
ArrayList list=new ArrayList();//使用Car作为泛型类型,以便可以调用所有Car方法
列表。添加(车辆1);
列表。添加(车辆2);
用于(汽车:列表)
{
System.out.println(car.getId());//迭代列表并检索每个元素ID
}
}