Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:从arraylist中的对象访问子类方法_Java_Oop_Arraylist - Fatal编程技术网

Java:从arraylist中的对象访问子类方法

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

我正在尝试从arraylist访问类Car中的方法。类层次结构基本上是:

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