Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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 如何避免搜索例程中的instanceof?_Java_Oop_Polymorphism - Fatal编程技术网

Java 如何避免搜索例程中的instanceof?

Java 如何避免搜索例程中的instanceof?,java,oop,polymorphism,Java,Oop,Polymorphism,目前,我正在对项目列表执行线性搜索,如下所示: private Item getKey(ArrayList<Item> inventory) { for(Item item : inventory) { if(item instanceof Key) { return item; } } return null; } private Item getKey(ArrayList库存){ 用于(项目:库存)

目前,我正在对项目列表执行线性搜索,如下所示:

private Item getKey(ArrayList<Item> inventory) {
    for(Item item : inventory) {
        if(item instanceof Key) {
            return item;
        }
    }
    return null;
}
private Item getKey(ArrayList库存){
用于(项目:库存){
if(项目实例键){
退货项目;
}
}
返回null;
}
我听说使用
instanceof
被认为是一种“代码气味”。通常,为了避免使用
instanceof
我会使用多态性(如中所述),然而,在这种情况下,我很难看到如何使用多态性


因此,我想知道是否有一种方法可以消除
instanceof
的需要,或许可以使用另一种技术,例如更加关注OOD的多态性?

您的案例与您的链接不同。我不认为您在本例中的代码是“代码气味”。
正如@shmosel提到的那样

此方法中没有缺陷

但您可以使代码更易于重用,因为:

private Item getKey(ArrayList<Item> inventory) {
    return getAnItemByType(inventory, Key.class);
}
private Item getAnItemByType(ArrayList<Item> inventory, Class<? extends Item> type) {
    for(Item item : inventory) {
        if(type.isInstance(item)) {
            return item;
        }
    }
    return null;
}
private Item getKey(ArrayList库存){
返回getAnItemByType(库存,Key.class);
}

private Item getAnItemByType(ArrayList inventory,Class如果您想要一个使用多态性而不是
instanceof
的解决方案,您需要在超类型中定义一个
isKey()
方法,并为符合键条件的子类型重写它:

public class Item {

    public boolean isKey() { 
        return false; 
    }
}

class Key extends Item {
    @Override
    public boolean isKey() {
        return true;
    }
}
然后,您的解决方案变成:

private Item getKey(ArrayList<Item> inventory) {
    for(Item item : inventory) {
        if(item.isKey()) {
            return item;
        }
    }
    return null;
}

你需要缩小。缺陷不在这个方法中。而是因为你正试图从
@shmosel的列表中提取一个
。啊,我明白你的意思。有没有更好的方法来表示库存的想法?你认为额外的
库存
类会有帮助吗?很难说没有更多上下文。@shmosel好的,我理解。谢谢你的提示:)这在同一级别上仍然有缺陷。类似地,您可以创建一个
int-type
字段(或者一个
enum-type
字段)。但是如果你有一个
对象的列表,然后想从中分离出
Foo
蓝精灵
对象,那么一切都会崩溃。问题是:为什么对象存储在同一个列表中,而它们在概念上如此不同,以至于之后需要按其类型对它们进行拆分?也许,它们首先应该存储在不同的列表中……是的,我同意这并不理想。但是,如果没有更广泛的设计背景,很难知道其他哪些约束可能会在这个决策中发挥作用。我试图尽可能具体地回答OP的问题。
private Optional<Item> getKey(ArrayList<Item> inventory) {
    return inventory.stream().filter( item -> item.isKey() ).findFirst();
}