java 的泛型 2

这篇也是初学JAVA的时候的心得

前言

刚刚学习Java.为了巩固自己的知识.就把自己对于Java语言的一些心得写出来,希望得到大家的斧正

集合类

Java中,所有从AbstractCollection继承下来的类都是一种比较特殊的类.比较类似于一个容器.例如比较常用的有ArrayList, Vector, HashMap, LinkedList 等.这些集合类的对象都有add或者put这2个方法把另外1个对象放到自己所占据的内存空间中.就好像一个"容器"一样.

让我们从一个例子开始把.有一家宠物店.我们为猫做了以下这个类

class Cat{
	protected int tag;
	public Cat(int n){
		tag=n;
	}
	public void showTag(){
		System.out.println("This is Cat #" + tag);
	}
}
定义一个集合类对象List catCage.使用以下代码把猫的一个实例放到集合类对象catCage中
catCage.add(new Cat(0));
catCage.add(new Cat(1));
当我们要使用集合类中的容纳了的类的方法的时候,可以用以下的代码实现
((Cat)catCage.get(0)).showTag();
((Cat)catCage.get(1)).showTag();
显示动物的标签这段代码我们可以使用以下的循环直接实现
for(int i=0;i<catCage.size();i++)
	((Cat)catCage.get(i)).showTag();
同理,对狗的处理也跟猫的雷同.有以下的2段代码
class Dog{
	protected int tag;
	public Dog(int n){
		tag=n;
	}
	public void showTag(){
		System.out.println("This is Dog #" + tag);
	}
}
dogCage.add(new Dog(0));
dogCage.add(new Dog(1));
for(int i=0;i<dogCage.size();i++)
	((Dog)dogCage.get(i)).showTag();
实际上,宠物店根本不需要为猫和狗准备2种笼子.以下代码使用一个cage集合对象来容纳Cat和Dog对象:
List cage=new ArrayList();

cage.add(new Cat(0));
cage.add(new Cat(1));
cage.add(new Dog(2));
cage.add(new Dog(3));
// 显示动物的标签
int i
for(i=0;i<2;i++)
	((Cat)cage.get(i)).showTag();
for(;i<4;i++)
	((Dog)cage.get(i)).showTag();
看到这里可能有些朋友就会问.既然这2个类都有相同的方法showTag(),为什么不能直接就用1个循环直接显示出来呢,就像下面的循环一次就把事情做完.
for(int i=0;i<cage.size();i++)
	((Cat)cage.get(i)).showTag();
大家试一下这段代码就知道运行的时候就会抛出一个运行时异常ClassCastException,这是因为Cat和Dog这2个类不能够转化而引发的异常.那如何才能够解决这个问题呢?这就引出了我们下一个话题

集合类中使用多态方法

这里必须重新定义上面的2个类.把他的公共类先抽象出来.建立一个抽象类Pet
abstract class Pet{
	protected int tag;
	public Pet(int n){
		tag=n;
	}
	public abstract void showTag();
}
在从Pet类继承出Cat和Dog
class Cat extends Pet{
	public Cat(int n){
		super(n);
	}
	public void showTag(){
		System.out.println("This is Cat #"+tag);
	}
}
class Dog extends Pet{
	public Dog(int n){
		super(n);
	}
	public void showTag(){
		System.out.println("This is Dog #"+tag);
	}
}
经过重新定义以后的Dog和Cat就可以利用面向对象编程的多态特性来实现.不同对象的相同方法.Cat和Dog还是没有办法互相转换。但是由于这2个类的共同方法都是实现了超类的抽象方法showTag().因此可以把这2个类都强制转换成超类,然后引用超类的showTag()方法,这里就使用了多态.
int i;
List cage = new ArrayList();
for(i=0;i<5;i++)
	cage.add(new Cat(i));
for(;i<10;i++)
	cage.add(new Dog(i));
//引用showTag()方法
for(i=0;i<cage.size();i++)
	((Pet)cage.get(i)).showTag();
到了这里,读者会发现集合对象cage好像可以容纳除了基本类型以外的任何对象,例如下面的代码
cage.add(new Integer(1));
但是当使用以下代码的时候又会抛出ClassCastException.
for(i=0;i<cage.size();i++)
	((Pet)cage.get(i)).showTag();
很显然,这样无缘无故的为cage对象增加一个与Pet完全无关的Integer对象,完全是程序员在编写代码时的失误,那么有没有办法把这个错误提前到在编译的时候就被发现呢?答案是肯定的这就涉及了Java 5.0出现的新特征"类参数"

使用类参数

对与类参数的支持是从5.0版开始的.类参数是用在声明一些集合类对象时指明集合对象能够容纳的类型.
List<Pet> cage = new ArrayList<Pet>();
在集合类List后面用<>括住了要使用的类型Pet.这样就限制了集合对象cage只能增加Pet类以及他的继承类.使用类参数有以下的优点:

首先是防止程序员发生以下的错误:
cage.add(new Integer(1));
这句代码的逻辑错误会在编译的时候就会被再编译的时候被发现,这样就避免了后面调用(Pet) cage.get(i).shwoTag() 时候发生 ClassCastException 的机会.

其次是消除了强制类型转换这种丑陋的语法.调用cage集合中的Pet对象的showTag()方法可以改为以下语句.
for(i=0;i<cage.size();++i)
    cage.get(i).showTag();
其实这个循环可以用5.0新增加的语法来改写:
for(Pet pet:cage)
    pet.showTag();

后话

这些文字好像是简单的教程,其实也是本人2个月来学习JAVA的一些总结。鉴于本人对Java的认识程度,有些地方的描述还不是很清晰。大家能够多提宝贵意见。也希望能够对刚刚接触面向对象编程的新手一些启示。

资源

文中提及的代码只要简单的增加上main()函数就可以了。如果想要完整的源代码,可以来信索取。

联系

我的联系方法:liangxiaowz at gmail dot com

参考资料

Using and Programming Generics in J2SE 5.0 - Qusay H. Mahmoud,
这是一篇在java.sun.com网站上官方的泛型编程入门介绍,上面有一些其他的关于泛型编程的其他资料的连接非常值得去看一下。具体连接我找不了。可以用关键字generics搜索一下。
其他的一些JAVA的教科书
这些我就不一一介绍了。我看的都是很显浅的入门书。主要是那些高级的JAVA书籍都太贵了。我都是在网上找去找更进一步的资料来学习JAVA的。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值