【笨鸟先飞】Java重新学习日记8---泛型的深入学习

泛型是将类型参数化以达到代码复用提高软件开发工作效率的一种特殊数据类型。

在使用时,泛型一般用于以下2种情况。

 

第一种情况:使用在集合当中,这是一种非常常见,而且用法很简单的情况,也是上一章没有深入讲解的部分,泛型在集合中用于定义集合的类型。从发展史上将,集合一开始是不使用泛型的,然后这样会导致传入类型的强制转换等诸多问题,于是引入了泛型。

在实际使用时,我们可以把集合的泛型作为一个必须的模板来使用,有了泛型的集合,使用起来可以避免各种令人困惑的故障,且增加了代码的可读性。

集合的泛型就是用来定义集合里面存放的对象是什么类型的。

 

ArrayList<keyboard>  kArray = new ArrayList<>();

 

Public void createKeyboard(Keyboard k1){

kArray.add(k1);

}

在例子中,创建了一个里面存放Keyboard类型的ArrayList。后面的尖括号“<keyboard>”这个就叫泛型,而作用就是,标识这个名字叫做kArray ArrayList,里面只能存放Keyboard 对象。

导致集合需要使用泛型,就要看集合为什么不能定义其内部的变量类型。

我一直说集合是数组的扩展,数组在创建的时候,是直接定义类型的,int[] a = new int[10];  直接就定义了是int,里面就只能放int,不能放其他。这是int是数据类型,而不是“类”

这个就有一个比较纠结的地方,集合本身就是一个类,也就是说,ArrayList本身就是一个类。按照正常类的创建方式是:

ArrayList a=new ArrayList( ) ;

于是在创建时,根本不知道这个a里面是放什么的,于是你什么都可以往里面放,数据,对象,字符串。如果真是这样放,在使用a的时候就乱套了。因为,数据,对象和字符串,几乎没有共同的方法。

于是泛型就出现了,在集合这里,它是给集合增加一个定义,定义集合里面放什么类型的对象,可以是数组,可以是对象,也可以是字符串。

ArrayList<int>  a= new ArrayList<>();

ArrayList<keyboard>  b= new ArrayList<>();

ArrayList<String>  c= new ArrayList<>();

这种定义之后的集合,用起来就和数组差不多了,b这个keyboard的集合,在传入了各类集合后,再通过get再来获取其方法,不会出现涉及判断的强转之类的故障。

还是按照因果关系来理解一下,面向对象的编程,相对较大的层次就会涉及到许多类,有些类它仅创建一个对象,有些类需要创建很多的对象。

用一个汽车驾驶模拟程序来举例子,方向盘应该只有一个对象,里面的参数是方向盘的形象,颜色等等,它的方法是可以控制汽车的转向。

赛道应该也是一个对象,里面的参数则包括道路两旁的树,两旁的建筑。

赛道这个对象里面,应该有这么一个集合,就是道路两旁的树。 道路两旁的树本身应该就是一个类,这个类的包括树的叶子,高度,颜色等等。在赛道里面,需要许多树这个类所创建的对象。

在使用循环的基础上,或许20棵树可以给用户带来无数棵树的感觉。那么,赛道里面的树是个集合,里面存放了有20个 树的对象。

ArrayList<Tree>  mRoadTree= new ArrayList<>();

这样就完成了赛道对象关于树的存放和传递,后面都用mRoadTree统一处理。

这里再换一个思路,这里如果只要两个树,那我们创建两个树的对象就ok。正是因为需要创建,存放,传递的树的这个对象,个数实在太多,我们“不得不”用集合把他包起来。

集合与泛型是在一起使用的,使用的时候,是同一个类创建的大量对象可以批量传递和处理。

对于大对象中包含的小对象,数量往往是客观的。特别是核心对象中,这种小对象出现的概率更高。

 

 

第二种情况:当传入参数为类的时候。用来定义未知的类,或者有范围的类。 在写顶层,或者框架级别的类的时候,这种类是用来给大家创建类的。这种时候也需要用到泛型。

仍然汽车驾驶模拟程序为例子。写一个赛道的框架,赛道的两边用来大家放入对象,这些对象可以是,房子和行人(城市赛道),树和花草(公路赛道),动物(野外赛道),乃至瀑布,落日,海滩(风景赛道)。

于是,我得这样写:

public static class Item<T> {
    public T mOwner;
  public T GetOwner() {
    return mOwner;
}

}

 

 

public Item<?>  GetItem(Class<?> ItemClass) {
    Class<? > result = get(ItemClass);
    try {
        return result != null ? result.newInstance() : new Item <ItemClass>();
    } catch (Exception e) {
        return new Item <ItemClass> ();
    }
}

 

 

 

这个一行一行解释一下。

首先是Item

第一行,创建了一个Item类,这个就是,这个类需要接收一个未知的类,当然实际上这个Item表达的是赛道周边的东西,而传入的都是程序员自己想添加的东西,包括在代码已经成熟的基础上,如果还想增加新的周边物品,也调用Item统一传入。

第二行,就是在类里面讲传入的对象,比如丛林赛道的猴子吧。传入猴子,这里取名为mOwner,就是传入的对象。

3行,GetOwner获取对象的方法,实际使用时,在其他模块会有一个地方,统一查询,一共传入了多少对象,多少类型,然后将传入的对象,合理的分布在赛道边缘。

 

然后是后面这个GetItem这方法,

第一行,可以看到,首先返回值就是Item类,而且里面到底放的什么对象都可以,只要是Item都可以。 其次传入值,传入的类的对象也不限制。也就是你写的赛道周围的对象,并不需要继承自某个类。毕竟猴子和大树和瀑布实在没有共同点。

第二行,get就是获取传入的类,这里要判断一下,当前类型是否已经传入过了,如果传入了,那么就能过get到以前传入过,如果没有get到,则返回null,表示还没有传入过。

第三行try。。Catch。。保护块,不展开说明,

第四行,这个判断是否为空,就是判断这个类是否已经有过。对于这个GetItem,是用来获取所有赛道路边物品这个Item类,每个类只需获取一次,不重复获取。如果这个类已经获取过了,那么我们就使用之前用这个类创建过的对象newInstance() 。如果这个类没有收到过,那么我们根据这个类,创建一个Item

 

上面代码实例,可以看出,这个功能,逻辑是比较复杂,在一般应用中,是用不上的,但是如果需要使用关于类传递的框架,就是你定义一个可以扩展的,大家都来用的,那么这个就很好用。

关于本文中“框架”这个词语,我想我是在表达,设计模式这个概念。一个巧妙的设计模式。

以上,就是关于泛型我的学习与思考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值