繁体   English   中英

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

[英]Java: Accessing subclass methods from objects in arraylist

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

class Vehicle {} 
class Car extends Vehicle {} 
class Chevy extends Car {}
class Ford extends Car {}

在此示例中, Car类具有名为getID()的吸气剂

main方法如下:

Ford vehicle1 = new Ford(id, model, etc);
Chevy vehicle2 = new Chevy(id, model, etc);

ArrayList<Vehicle> list = new ArrayList<Vehicle>();
list.add(vehicle1);
list.add(vehicle2);

通过大量的试验,我能够像这样访问错误getID()方法:

System.out.println("Vehicle ID: " + ((Chevy) list.get(1)).getID());

哪个可行...我简直无法想象自己正在以正确的方式进行操作。 有没有更好的方法来访问这些子类方法?

对于严肃的程序,您的Vechicle接口应定义所有车辆通用的所有行为方法,其中应包括getID()方法。 但是,在某些情况下,您可能希望有一种适用于特定类型车辆的特定方法。 那么您需要在Vehicle子类或子接口中执行此操作。 以上面的示例为例,您可能希望拥有一个带有该getID()方法的NamedVehicle 如何安排接口和类取决于您。 如果有帮助,请参考网桥设计模式。

综上所述,您确实希望在非常偶然的地方进行显式转换。

在列表中添加子类对象看起来不错,但是当您遍历列表时,您将永远不知道将访问哪个子对象。

我建议您可以通过以下方式使父对象指向子对象。

Car vehicle1 = new Ford(id, model, etc);
Car vehicle2 = new Chevy(id, model, etc);

然后添加到列表中,如图所示。 当您遍历列表时,您将根据instanceof check将其向下转换,这将使其更加传统。

例如:

Car c = (Car)list.get(0)).getID();
if(c instanceof Ford){

    Ford f = (Ford)c;
    System.out.println(f.getId());

}

为什么车辆不是接口(类无法扩展接口,而是实现了接口)?

据我了解,而Car却没有VehiclegetId() ,这就是为什么不将Vehicle数组列表对象转换为具有此类方法(如Chevy )的子类会导致错误的原因。

如果您这样做:

System.out.println("Vehicle ID: " + ((Car) list.get(1)).getID());

它会工作的。

我建议您将Vehicle为界面:

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

由于getId()方法是在Car类中声明的,因此您只能通过继承来访问此方法( 当然,需要用protectedpublic修饰符标记 )。

因此, Car任何子类都可以访问getId()方法,并且应该具有在Car#getId标记的行为,除非该方法在相关子类型中被覆盖 ,因此在运行时将根据当前对象类型和方法来评估方法的行为。不是对象引用。

现在介绍最著名的OO(面向对象)功能之一,即多态 (许多形式),它使您可以传递需要Car任何Car子类型,并在需要Car实例时返回任何Car子类型。

因此,要sumup,你能有什么Car亚型在ArrayListCar (S): FordChevy ,你就能再调用任何Car上的列表中的任何项目实例方法(这是什么真正的类型,它不无关紧要,因为它是Car的孩子)。

现在的主要问题是,所描述的行为不能在另一侧进行,因此,除非在``''下满足显式强制转换,否则父引用 (在您的情况下为Vehicle )将永远不会知道其后代的行为(在您的情况下为Car )。路。

然后,您只需要简单地使用Car作为泛型类型来实例化ArrayList (这就是您说<Vehicle><Car>时所做的事情):

public static void main(String[] args)
{
  Ford vehicle1 = new Ford(id, model, etc);
  Chevy vehicle2 = new Chevy(id, model, etc);

  ArrayList<Car> list = new ArrayList<Car>(); //Use a Car as generic type so you can call all car methods
  list.add(vehicle1);
  list.add(vehicle2);

  for(Car car : list)
  {
    System.out.println(car.getId()); // Iterate over the list and retrieve each element ID
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM