簡體   English   中英

Java generics 返回泛型參數化為更具體的兩種類型?

[英]Java generics return generic paramaterized as more specific of two types?

我目前有一個項目,我正在使用一組實現通用Filter<T extends Entity> class 的類來過濾一些實體,其中 T 是特定過濾器將處理的最具體的實體。 一直在創建新實例有點冗長,所以我還構建了一個 Builder。 除了現在我試圖將 AndFilter 添加到構建器之外,一切都很棒。

這是我的 AndFilter 的樣子

public class AndFilter<T extends Entity> implements Filter<T>{
    private Filter<? super T> a;
    private Filter<? super T> b;

    public AndFilter(Filter<? super T> a, Filter<? super T> b){
        this.a = a;
        this.b = b;
    }

    @Override
    public boolean shouldInclude(T entity) {
        return a.shouldInclude(entity) && b.shouldInclude(entity);
    }
}

這是我一直在努力工作的建築function(我的構建器只是過濾器界面中的默認功能)

public interface Filter<T extends Entity> {
    boolean shouldInclude(T entity);

    default AndFilter and(Filter<? extends Entity> other){
        return new AndFilter<>(this, other);
    }

    default Filter<T> not(){
        return new NotFilter<>(this);
    }
}

我需要能夠參數化 and() 的返回,但我所做的所有嘗試都失敗了。 理論上,應該將 AndFilter 參數化為 this 或 other 的類型,以更具體者為准,但我不知道我該怎么做,我開始認為這根本不可能。 如果不是,任何關於我可以實現類似行為的替代方法的建議(不必調用 new AndFilter<>(x, y) 來比較兩個過濾器)將不勝感激。

編輯:我有各種繼承自 Entity 的類,它們都有自己的私有屬性。

實體 -> 動物 -> 捕食者,Grazor

實體 -> 障礙

實體 -> 植物

所以我有一個 DistanceFilter 實現了過濾器(因為所有實體都有位置,因此有距離),但我也有 AggressionFilter 實現了過濾器,因為只有掠食者才有攻擊屬性。 檢查捕食者是否滿足兩個過濾器應該是可能的,因為捕食者具有所有必需的屬性,並且確實有效。 我可以調用 new AndFilter<>(new DistanceFilter(), new AggressionFilter()) 並且它工作正常,但是當我嘗試將初始化放在 function 后面時,我無法讓返回類型工作

AndFilter 有一個參數化類型,AndFilter 應該被 T 綁定。AndFilter 應該由與其綁定的相同類型的 Filter 對象組成, T擴展了 Entity。

default AndFilter<T> and(Filter<? extends Entity> other){
    return new AndFilter<>(this, other);
}
public class AndFilter<T extends Entity> implements Filter<T>{

    private Filter<T> a;

    private Filter<T> b;

    public AndFilter(Filter<T> a, Filter<T> b){
        this.a = a;
        this.b = b;
    }
}

使用 class MyEntity的示例實現,它擴展了 Entity 並具有字符串類型的單個 class 成員name

        MyEntity foo = new MyEntity("Foo");

        MyEntity bar = new MyEntity("Bar");

        MyEntity fooBar = new MyEntity("FooBar");

        Filter<MyEntity> fooFilter = e -> e.name.contains("Foo");

        Filter<MyEntity> barFilter = e -> e.name.contains("Bar");

        Filter<MyEntity> fooBarFilter = fooFilter.and(barFilter);

        System.out.println(String.format("Foo: %s", fooFilter.shouldInclude(foo)));
        System.out.println(String.format("Bar: %s", barFilter.shouldInclude(bar)));
        System.out.println(String.format("FooBar: %s", fooBarFilter.shouldInclude(fooBar)));

我終於想出了如何解決我自己的問題

default <F extends T> AndFilter<F> and(Filter<? super F> other){
    return new AndFilter<>(this, other);
}

必須給 function 它自己的通用類型 (F),它至少是當前過濾器的類型,然后另一個過濾器最多只能是那種類型。 返回的 AndFilter 被參數化為該類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM