[英]Java: Accessing subclass methods from objects in arraylist
I am trying to access methods in the class Car from my arraylist. 我正在尝试从我的arraylist访问Car类中的方法。 The class hierarchy is essentially: 类层次结构本质上是:
class Vehicle {}
class Car extends Vehicle {}
class Chevy extends Car {}
class Ford extends Car {}
In this example Car
class has a getter called getID()
在此示例中, Car
类具有名为getID()
的吸气剂
The main
method looks like this: 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);
Through a lot of trial an error I've been able to access the getID() method like so: 通过大量的试验,我能够像这样访问错误getID()方法:
System.out.println("Vehicle ID: " + ((Chevy) list.get(1)).getID());
Which works... I just can't imagine I'm doing this the proper way. 哪个可行...我简直无法想象自己正在以正确的方式进行操作。 Is there a better way to access these sub class methods? 有没有更好的方法来访问这些子类方法?
For a serious program, your Vechicle
interface should define all the behavioral methods common to all vehicles, which should include your getID()
method. 对于严肃的程序,您的Vechicle
接口应定义所有车辆通用的所有行为方法,其中应包括getID()
方法。 However, in some cases you might want to have specific method that only applies to a certain type of vehicles; 但是,在某些情况下,您可能希望有一种仅适用于特定类型车辆的特定方法。 then you need to either do that in subclasses or sub interfaces to Vehicle
. 那么您需要在Vehicle
子类或子接口中执行此操作。 Take your above example, you might want to have a NamedVehicle
with that getID()
method. 以上面的示例为例,您可能希望拥有一个带有该getID()
方法的NamedVehicle
。 How to arrange your interfaces and classes is up to you. 如何安排接口和类取决于您。 Refer to bridge design pattern if that helps. 如果有帮助,请参考网桥设计模式。
Having said the above, in very occasional places you do want to do the explicit cast. 综上所述,您确实希望在非常偶然的地方进行显式转换。
Adding a subclass objects in the list seems fine, but u would never know which child object would be accessed when iterating over the list. 在列表中添加子类对象看起来不错,但是当您遍历列表时,您将永远不知道将访问哪个子对象。
I would suggest you could have parent reference point to child object in the following way. 我建议您可以通过以下方式使父对象指向子对象。
Car vehicle1 = new Ford(id, model, etc);
Car vehicle2 = new Chevy(id, model, etc);
And add then to list as seen. 然后添加到列表中,如图所示。 When you iterate over the list u would downcast it based on the instanceof check, which would make it more conventional. 当您遍历列表时,您将根据instanceof check将其向下转换,这将使其更加传统。
ex: 例如:
Car c = (Car)list.get(0)).getID();
if(c instanceof Ford){
Ford f = (Ford)c;
System.out.println(f.getId());
}
Why vehicle isn't an interface (classes cannot extend interfaces, they implement it)? 为什么车辆不是接口(类无法扩展接口,而是实现了接口)?
As far as I understood Vehicle
doesn't have a getId()
while Car
does, that's why not casting your Vehicle
array list object to a subclass which has such method (like Chevy
) causes an error. 据我了解,而Car
却没有Vehicle
的getId()
,这就是为什么不将Vehicle
数组列表对象转换为具有此类方法(如Chevy
)的子类会导致错误的原因。
If you did: 如果您这样做:
System.out.println("Vehicle ID: " + ((Car) list.get(1)).getID());
it would have worked. 它会工作的。
I suggest you to make Vehicle
an interface: 我建议您将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;
}
}
With this configuration you can do: 使用此配置,您可以执行以下操作:
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
Since the getId()
method is declared in the Car
class, then you can only access this method through inheritance ( of cource need to be marked with either of access modifiers protected
or public
). 由于getId()
方法是在Car
类中声明的,因此您只能通过继承来访问此方法( 当然,需要用protected
或public
修饰符标记 )。
So any subclass of Car
will have access to the getId()
method and should have the behavior marked in the Car#getId
unless that method is overriden in the related subtype thus at runtime the method behavior will be evaluted based on the current object type and not the object reference. 因此, Car
任何子类都可以访问getId()
方法,并且应该具有在Car#getId
标记的行为,除非该方法在相关子类型中被覆盖 ,因此在运行时将根据当前对象类型和方法来评估方法的行为。不是对象引用。
Now coming to one of the most famous OO (Object Oriented) features which is polymorphism (many forms) which let you pass any Car
subtype where a car is needed, and return any Car
subtype when you expect a Car
instance. 现在介绍最著名的OO(面向对象)功能之一,即多态 (许多形式),它使您可以传递需要Car
任何Car
子类型,并在需要Car
实例时返回任何Car
子类型。
So to sumup, you can have any Car
subtype in an ArrayList
of Car
(s): Ford
, Chevy
and you will be able then to call any Car
instance method on any item of the list (whatever real type it is, it does not matter since it is a child of Car
). 因此,要sumup,你能有什么Car
亚型在ArrayList
的Car
(S): Ford
, Chevy
,你就能再调用任何Car
上的列表中的任何项目实例方法(这是什么真正的类型,它不无关紧要,因为它是Car
的孩子)。
The main issue now is that the described behavior can't go in the other side, so a parent reference (in you case Vehicle
) would never know about its descendants behavior (the Car
in your case) unless an explicit cast is met under the road. 现在的主要问题是,所描述的行为不能在另一侧进行,因此,除非在``''下满足显式强制转换,否则父引用 (在您的情况下为Vehicle
)将永远不会知道其后代的行为(在您的情况下为Car
)。路。
Then you will need simply put, to instantiante your ArrayList
using the Car
as a Generic type (that's what you are doing when you say <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.