我现在有一个问题,这让我想到了一个关于Java及其继承机制的更普遍的问题。
有一个抽象类,我需要扩展,它看起来像这样:
public abstract class RichFlatMapFunction<IN, OUT> extends AbstractRichFunction implements FlatMapFunction<IN, OUT> {
private static final long serialVersionUID = 1L;
@Override
public abstract void flatMap(IN value, Collector<OUT> out) throws Exception;
}
因此,在我的实现中,我希望(需要(覆盖函数flatMap()
。我自己的类使用<Tuple2<GenericRecord,GenericRecord>, Tuple2<GenericRecord,GenericRecord>>
作为 IN 和 OUT 参数。
现在,我尝试覆盖此flatMap()
函数,而不是接口Collector<OUT>
而是使用该接口的实现,如下所示:
public class TupleWrappingCollector<IN, K> implements Collector<IN> {...}
据我了解,我应该能够使用这个类而不是Collector<OUT>
,因为它满足函数所需的这个接口。定义一个TupleWrappingCollector<Tuple2<GenericRecord,GenericRecord>, GenericRecord>
将导致使用Collector<Tuple2<GenericRecord,GenericRecord>>
实现接口,这正是初始类中flatMap()
函数所需要的,另一个参数GenericRecord
类中的某个地方,这在这里无关紧要。 但是,在尝试定义方法标头时,我会看到一个错误,如下所示:
public void flatMap(Tuple2<GenericRecord,GenericRecord> value, TupleWrappingCollector<Tuple2<GenericRecord,GenericRecord>, GenericRecord> out) {...}
没有发现被重写的方法,并且该类要求我为Tuple2<GR,GR>, Collector<Tuple2<GR,GR>>
指定一个flatMap()
函数,我不明白为什么。在我看来,我正在实现指定的方法标头。
我在这里错过了什么,implements
是否取消了我用作有效参数的类的资格,或者我对接口的缩小/加宽有错误的把握?
要履行RichFlatMapFunction::flatMap
的契约,你必须提供一个可以与任何Collector<OUT>
实现一起使用的函数。
通过将方法声明更改为Collector<OUT>
的特定实现,您将无法将此函数应用于不是TupleWrappingCollector<OUT, K>
子类的接口的其他实现。
举个例子:你的RichFlatMapFunction
实现将无法处理以下Collector
,但根据合约,它应该这样做:
public class MyCollector<OUT> implements Collector<OUT> {...}