Java基础(九):范型的自限定类型

x33g5p2x  于2021-09-25 转载在 Java  
字(2.7k)|赞(0)|评价(0)|浏览(283)

1、范型自限定类型

class SelfBounded<T extends SelfBounded<T>>

作者说道:

这就像两面镜子彼此照向对方所引起的目眩效果一样,是一种无限反射。

SelfBounded类接受泛型参数T,T由一个边界限定,这个边界就是拥有T作为其参数的SelfBounded

理解:

首先是范型类A,有个范型参数T,范型参数T有边界限定,边界限定就是有参数T的范型类A

class SelfBounded<T extends SelfBounded<T>> {}

class A extends SelfBounded<A> {}//正常
class B extends SelfBounded<A> {}//正常

// compile error:Type parameter 'B' is not within its bound; should extend SelfBounded<B>'
// 编译器提示:因为 class B extends SelfBounded<A>  不满足条件:T extends SelfBounded<T> 
// 如何才能满足条件呢?将类B的定义改为class B extends SelfBounded<B>,
class D extends SelfBounded<B> {}//编译错误

两种方式使class D编译通过

  • 将类B的定义改为class B extends SelfBounded<B>
  • 将 SelfBounded 的定义修改为:class SelfBounded<T extends SelfBounded>

2、普通范型

  • BasicHolder<T>泛型类的类型参数T没有边界,此时可以class A extends BasicHolder<B> {}这样使用。
  • 自限定格式:class Subtype extends BasicHolder<Subtype> {}。                                          从定义上来说,它继承的父类的类型参数是它自己。                                                                  从使用上来说,Subtype对象本身的类型是Subtype,且Subtype对象继承而来的成员(element)、方法的形参(set方法)、方法的返回值(get方法)也是Subtype了。
  • 自限定重要作用:Subtype对象就只允许和Subtype对象(而不是别的类型的对象)交互
  • 自限定的用法:父类作为一个泛型类或泛型接口,用子类的名字作为其类型参数
class BasicHolder<T> {
    T element;
    void set(T arg) { element = arg; }
    T get() { return element; }
    void f() {
        System.out.println(element.getClass().getSimpleName());
    }
}

class Subtype extends BasicHolder<Subtype> {}

public class CRGWithBasicHolder {
    public static void main(String[] args) {
        Subtype st1 = new Subtype(), st2 = new Subtype(), st3 = new Subtype();
        st1.set(st2);
        st2.set(st3);
        Subtype st4 = st1.get().get();
        st1.f();
    }
} 
Subtype

用法:一个普通的泛型类我们可以继承它来做到自限定

  1. 定义一个范型类;
  2. 定义子类继承该范型类,且范型参数是子类本身。

3、自限定类型范型

class SelfBounded<T extends SelfBounded<T>> {//自限定类型的标准用法
    //所有
    T element;
    SelfBounded<T> set(T arg) {
        element = arg;
        return this;
    }
    T get() { return element; }
}

class A extends SelfBounded<A> {}

public class SelfBounding {
    public static void main(String[] args) {
        A a = new A();//a变量只能与A类型变量交互,这就是自限定的妙处
        SelfBounded<A> b =  new SelfBounded<A>();
    }
} ///:~
  •         SelfBounded泛型类类型参数T有SelfBounded<T>的边界要求。因为要使用SelfBounded泛型类之前,我们必须有一个实际类型能符合SelfBounded<T>的边界要求,所以这里就,创建一个新类来符合这个边界,即class A extends SelfBounded<A> {},这样新类A便符合了SelfBounded<T>的边界。

4、用途

自限定类的用途为保证 子类对基类型成员函数的重写

4.1、基本类导致不能覆盖父类函数

public class Basic{
    Basic b;
    public void set(Basic b){ this.b = b; }

    public static void main(String[] args) {
        SubType st = new SubType();
        st.set(new SubType());		//正常,调用了SubType类本身的set函数
        st.set(new Basic());		//正常,调用了继承自Basic的set函数

    }
}

class SubType extends Basic{
    SubType b;

    //SubType类还隐式继承了Basic的set函数,没有被重写的set函数覆盖
    public void set(SubType b){ this.b = b; }
}

4.2、自限定类保证函数重写

public class Basic<T extends Basic<T>>{
    T b;
    public void set(T b){ this.b = b; }

    public static void main(String[] args) {
        SubType st = new SubType();
        st.set(new SubType());		//正常
        st.set(new Basic());		//编译报错,调用了继承自Basic的set函数,并且限制类行为SubType
    }
}
class SubType extends Basic<SubType>{}

参考:Java泛型之自限定类型 - 公子姓王 - 博客园

相关文章

微信公众号

最新文章

更多