Java,如何基于对象的一个接口重新转换对象?
我有一组类实现接口Java,如何基于对象的一个接口重新转换对象?,java,interface,casting,Java,Interface,Casting,我有一组类实现接口Paintable和Tickable。 另一个类,World,通过将这些类推到ArrayList中来跟踪它们 我有一个不同的类,它处理所有可绘制的对象,获取所有这些对象的可靠方法是使用getPaintables()方法向world请求,因为world持有的所有对象都是可勾选和可绘制的 当我尝试将Tickable对象转换为Paintable对象时,出现了如下问题: for (Paintable p : (ArrayList<Paintable>)world.g
Paintable
和Tickable
。
另一个类,World
,通过将这些类推到ArrayList
中来跟踪它们
我有一个不同的类,它处理所有可绘制的对象,获取所有这些对象的可靠方法是使用getPaintables()方法向world请求,因为world
持有的所有对象都是可勾选和可绘制的
当我尝试将Tickable
对象转换为Paintable
对象时,出现了如下问题:
for (Paintable p : (ArrayList<Paintable>)world.getPaintables()) {
// Do stuff
}
for(Paintable p:(ArrayList)world.getpaintable()){
//做事
}
这导致:
error: incompatible types: ArrayList<Tickable> cannot be converted to ArrayList<Paintable>.
错误:不兼容的类型:ArrayList无法转换为ArrayList。
有没有可能通过其他方式来解决这个问题?当然,我可以在World
中复制ArrayList
,一个作为Paintable
,另一个作为Tickable
,但这对我来说似乎很麻烦
我希望这是有道理的。我不完全明白你的问题,但我会试一试
如果world.getPaintables()返回List,则很明显您的代码不起作用
如果world.getPaintables()同时包含这两个对象,则可以对可勾选和可绘制对象执行类似于Louis所说的操作:
for (Object p : (ArrayList<Object>)world.getPaintables()) {
if (p instanceof Paintable)
paint();
else if (p instanceof Tickable)
tick();
}
(对象p:(ArrayList)world.getPaintables()的{
if(可涂漆的p实例)
油漆();
else if(可勾选的p实例)
勾选();
}
我认为“修复”这一问题的最简单方法就是创建一个公共界面,并将其用于所有列表。如果您的所有类都实现了Tickable
和Paintable
,那么您可能无论如何都应该这样做
public class TickAndPaint
{
public static void main(String[] args) {
ArrayList<TickableAndPaintable> list = new ArrayList<>();
for( Paintable t : list ) {
}
for( Tickable t : list ) {
}
}
}
interface Paintable {}
interface Tickable {}
interface TickableAndPaintable extends Paintable, Tickable {}
公共类TickAndPaint
{
公共静态void main(字符串[]args){
ArrayList=新建ArrayList();
用于(可绘制的t:列表){
}
for(可勾选的t:列表){
}
}
}
接口可绘制{}
接口可勾选{}
接口TickableAndPaintable扩展了Paintable,Tickable{}
返回world.getPaintables()的数据类型是什么?
如果该方法的返回值是Paintable的ArrayList,则不应强制转换任何内容。
无论如何,您可以做如下操作:
for(Object p : world.getPaintables()) {
if(p instanceOf Paintable){
(Paintable)p ... (do something);
}
}
希望它能帮助你。你根本不需要打字。在World
上实现Iterable
和Iterable
,然后您可以简单地为(Paintable p:World)
或为(Tickable t:World)执行操作,而无需进行类型转换。一种不需要更改类/接口层次结构的替代方法,是在您的世界
类中声明具有多个边界的列表
容器。例如:
class World<T extends Object & Paintable & Tickable> {
private List<T> tickablePaintables = new ArrayList<>();
/*...*/
public List<T> getTickablePaintables() {
return tickablePaintables;
}
/*...*/
}
由于Java中类型参数的工作方式,不幸的是,这会给类/方法声明(用于声明T
)增加一些混乱。最简单的事情可能是强制转换单个对象,而不是整个列表。它们必须有一个公共基类,然后您可以强制转换到该类。您应该先阅读本教程。@GergelyKőrössy它们都是不同超类的现成子类。@LouisWasserman我也这么想,但当我需要调用特定于接口的方法时,这会导致更深层次的问题。@Jarmund通常可以在不进行类型转换的情况下实现大部分内容。当您需要在某个对象中迭代某个对象时,对要迭代的每个类型使用Iterable
接口,这样您就不需要类型转换了。请看下面我的答案。返回的所有对象都是可勾选和可绘制的,然后您应该按照marspace的建议执行操作!虽然有些臃肿,但这是迄今为止最干净的方法。谢谢
public <T extends Object & Paintable & Tickable> void doSomething() {
World<T> w = new World<>();
for (Tickable tickable : w.getTickablePaintables()) {
//...
}
for (Paintable paintable : w.getTickablePaintables()) {
//...
}
}