美文网首页
自身类型

自身类型

作者: 风干鸡 | 来源:发表于2017-02-06 16:55 被阅读0次

    自身类型

    Scala里面有自身类型,这个东西相当于方法隐藏的this参数的类型。

    有了这个东西,可以写出这样的代码。

    class A {
      def fun1(): this.type = {
        this
      }
    }
    
    class B extends A{
      def fun2(): this.type = {
        print("b")
        this
      }
    }
    
    object Test{
      def main(args: Array[String]): Unit = {
        new B().fun1().fun2()
      }
    }
    
    

    而java就不可以这样,比如同样的代码,用Java写出来:

    public class Test{
        public static void main(String[] args){
            new B().fun1().fun2();
                          ^ 这里会报错
        }
    }
    
    class A{
        A fun1() {
            return this;
        }
    }
    
    class B extends A{
        B fun2() {
            return this;
        }
    }
    

    因为fun1()的返回值类型是A而不是B,Java支持协变返回类型,但是要在子类中覆盖。

    class B extends A{
        @Override
        B fun1() {
            return (B) super.fun1();
        }
    
        B fun2() {
            return this;
        }
    }
    

    这样功能虽然相同,但是很多余。

    如果把方法当成函数,把隐藏的this参数展开,用静态方法来表示:

    class A{
        static <E extends A> E fun1(E this$) {
            //do something whit this$
            return this$;
        }
    }
    

    这样就很清晰了,事实上this.type 就是隐藏this参数的类型参数,而他依据调用方法的对象来推导出返回值的类型。

    上面的代码就可以改成:

    public class Test{
        public static void main(String[] args){
            B b = new B();
            fun2(fun1(b));
        }
    }
    
    class A{
        static <T extends A> T fun1(T this$) {
            //do something whit this$
            return this$;
        }
    }
    
    class B extends A{
        static <T extends A> T fun2(T this$) {
            return this$;
        }
    }
    

    功能完全一致,但是他是静态方法不能用.调用,如果说写这样的代码就是为了方便链式调用的话,这样肯定是不符合要求的。

    那么返回值就只能用泛型了(继承的时候需要手动指定类型参数)。

    public class Test{
        public static void main(String[] args){
            new B().fun1().fun2();
        }
    }
    
    class A<T extends A<T>>{
        T fun1() {
            return (T) this;
        }
    }
    
    class B extends A<B> {
        B fun2() {
            return null;
        }
    }
    

    非常的难看。

    相关文章

      网友评论

          本文标题:自身类型

          本文链接:https://www.haomeiwen.com/subject/rsduittx.html