Can we represent “self class” in Java (or Kotlin)?

I think the question title is a little bit confusing, but I can't find a mo…
关注者
44
被浏览
5,275
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

研究了一下。 即使用了高票所说的Curiously recurring template pattern。 还是不能保证所有情况。

用OP的例子:


interface A { A bla(); }


如果用CRTP:

interface A<T extends A<T>>{
    T bla();
}

看上去是可以了:

class B implements A<B> {
    @Override
    public B bla() {
        return this;
    }
}

而这个 A<T extends A<T>> 其实是为了保证 你不能这么用


//这里String并不是 A<String>的继承类。所以编译错误。
class B implements A<String> {

    @Override
    public String bla() {
        return "";
    }
}


但其实这样也是可以的:

//仍旧可以编译
class B implements A{
    @Override
    public A bla() {
        return this;
    }
}

甚至这样也是可以的:

class C implements A<C> {

    @Override
    public C bla() {
        return null;
    }
}

class D extends C {

}

class E implements A<C> {

    @Override
    public D bla() {
        return null;
    }
}
//或者这样

class D extends C {

    @Override
    public D bla() {
        return new D();
    }
}

总结:

在Java上应该是不行的。

但是我们来看下一个常见的Java上的monad是怎么实现你说的的这个 bind

public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper) {
    return flatMap(mapper, false);
}

也没有对类型进行特别强制的要求。