Java 铸造谓词<&燃气轮机;子类型

Java 铸造谓词<&燃气轮机;子类型,java,casting,polymorphism,functional-interface,Java,Casting,Polymorphism,Functional Interface,我有一个谓词的自定义实现,我想在一些操作中使用它。 然而,我有一个艰难的类型使多态性与它一起工作 经过一些调查后,我编写了下面的最小代码来重现这个问题(这是一个比我所能描述的更好的问题解释) 类自定义实现谓词{ int-y; 公共海关(国际){ 这个。y=y; } @凌驾 公共布尔测试(整数i){ 返回y+i>0; } } 公共班机{ 公共静态void main(字符串[]args){ 自定义c1=新自定义(5); 定制c2=新定制(8); 自定义c=(自定义)c1.和(c2);//线路故障-无

我有一个
谓词的自定义实现,我想在一些操作中使用它。
然而,我有一个艰难的类型使多态性与它一起工作

经过一些调查后,我编写了下面的最小代码来重现这个问题(这是一个比我所能描述的更好的问题解释)

类自定义实现谓词{
int-y;
公共海关(国际){
这个。y=y;
}
@凌驾
公共布尔测试(整数i){
返回y+i>0;
}
}
公共班机{
公共静态void main(字符串[]args){
自定义c1=新自定义(5);
定制c2=新定制(8);
自定义c=(自定义)c1.和(c2);//线路故障-无法强制转换
}
}

我不确定强制转换失败的原因以及如何使其工作。

如果您想保留
自定义
对象的状态并实现
谓词
接口,我建议重载
否定
方法。当您将两个
自定义
对象与
组合时,或者当您调用
否定
时,您将得到一个
自定义
对象作为返回值。当您将
自定义
对象与
谓词a.test(i)| | b.test(i)的任何其他实现相结合时;
这个a=a;
这个.b=b;
}
}
类不扩展自定义{
风俗习惯;
公共非(自定义){
超级((i)->!自定义测试(i));
这个习惯=习惯;
}
}
私有最终谓词;
公共海关(国际){
这((i)->y+i>0);
}
私有自定义(谓词){
this.predicate=谓词;
}
@凌驾
公共布尔测试(整数i){
返回谓词test(i);
}
公共习惯和(其他习惯){
返回新的自定义项。和(此项,其他项);
}
公共习惯。或(其他习惯){
返回新的自定义项。或(此项,其他项);
}
公共习惯。不否定(){
返回新的自定义项。不是(此);
}
}

我看不出创建此类谓词的好理由,因为它会使谓词复杂化。然而,在我看来,至少有3种不同的方式“改变”谓词状态

v0-只需使用
java.util.function.Predicate
final谓词p1=“foo”::等于;
最后一个谓语unit1=p1.or(“条”::等于);
Assertions.assertTrue(unit1.test(“foo”);
Assertions.assertTrue(unit1.test(“bar”));
assertFalse(unit1.test(“baz”));
最后一个谓语unit2=p1.or(“baz”::等于);
Assertions.assertTrue(unit2.test(“foo”));
Assertions.assertTrue(unit2.test(“baz”));
这段代码没有什么问题,我仍然坚持不实现任何自定义类

v1在自定义谓词实现中的“do cast” 这仍然需要重写
谓词
接口中的所有默认方法,以便在将来的Java版本中不会中断

公共抽象类V1MutablePredicate
实现谓词{
@可空
私有最终谓词;
受保护的V1MutablePredicate(@Nullable final Predicate){
this.predicate=谓词;
}
保护抽象布尔点测试(T);
@非空
受保护的抽象P wrap(@Nonnull谓词);
@凌驾
公共最终布尔测试(最终T){
返回谓词==null?doTest(t):predicate.test(t);
}
@非空
@凌驾

公开期末考试(@Nonnull final Predicate默认
方法的结果返回一个
谓词
的实现,该实现不知道您的
自定义
。要使其工作,请覆盖
自定义
中的
方法。但通常您不应该执行此类强制转换,而只是更喜欢
谓词
@fluffy>如何重写
?我做了一些尝试,但失败了。另外,我创建了
自定义
类,因为其中有
y
属性(我需要保留一些状态).有没有其他方法呢?我的意思是,你真的需要转换为
自定义
而不是将其称为
谓词
?多态性和“子类型”通常适用于
扩展
(派生类)的用法,而不是
实现
(实现接口).我不是说你应该扩展
谓词
,而是说这里发生了一些事情。@fluffy
测试
根据
自定义
对象的状态进行复杂的正则表达式匹配。我应该能够做
自定义.sety(newY)
,这会影响测试结果。因此,我实现了一个自定义谓词,而不是像函数式编程那样使用它。
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
    }
}

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);
    }

}