首页 > 解决方案 > 将 Predicate<> 转换为子类型

问题描述

我有一个Predicate我想在某些操作中使用的自定义实现。但是,我有一种很难使用多态性的类型。

经过一番调查,我在下面编写了最小的代码来重现问题(这是对问题的更好解释,比我能描述的还要好)。

class Custom implements Predicate<Integer> {
    int y;
    
    public Custom(int y) {
        this.y = y;
    }
    
    @Override
    public boolean test(Integer i) {
        return y+i>0;
    }
}


public class Main{
    
    public static void main(String[] args) {
            Custom c1 = new Custom(5);
            Custom c2 = new Custom(8);
            Custom c = (Custom) c1.and(c2); // faulty line - unable to cast
    }
}

我不确定为什么铸造失败以及如何使其发挥作用。

标签: javacastingpolymorphismfunctional-interface

解决方案


如果您想保留Custom对象的状态并实现Predicate接口,我建议重载and,ornegate方法。当您将两个Custom对象与结合时andor或者当您调用时,negate您将获得一个Custom对象作为返回值。当您将Custom对象与Predicate<Integer方法的任何其他实现结合起来时,仍然会返回Predicate<Integer

class Custom implements Predicate<Integer> {

    class And extends Custom {

        Custom a;
        Custom b;

        public And(Custom a, Custom b) {
            super((i) -> a.test(i) && b.test(i));
            this.a = a;
            this.b = b;
        }
    }

    class Or extends Custom {

        Custom a;
        Custom b;

        public Or(Custom a, Custom b) {
            super((i) -> a.test(i) || b.test(i));
            this.a = a;
            this.b = b;
        }
    }

    class Not extends Custom {

        Custom custom;

        public Not(Custom custom) {
            super((i) -> !custom.test(i));
            this.custom = custom;
        }
    }

    private final Predicate<Integer> predicate;

    public Custom(int y) {
        this((i) -> y + i > 0);
    }

    private Custom(Predicate<Integer> predicate) {
        this.predicate = predicate;
    }

    @Override
    public boolean test(Integer i) {
        return predicate.test(i);
    }

    public Custom.And and(Custom other) {
        return new Custom.And(this, other);
    }

    public Custom.Or or(Custom other) {
        return new Custom.Or(this, other);
    }

    public Custom.Not negate() {
        return new Custom.Not(this);
    }

}

推荐阅读