Java泛型一:泛型作为方法参数;【泛型作为方法参数】和【方法重载】的关联;?和T的区别(未写);

为什么需要泛型?

如一个问题:Set set1 = new Set();定义了一个Cat类;向set1集合中添加cat对象;当遍历set1时候,需要用到Iterator迭代器;Iterator it = set1.iterator();其中需要用到的it.next()的方法的返回值是Object类型的,如果要调用Cat类中定义的方法就需要把返回值转型为Cat类型。但如果错误地写成:String c1 = (String)it.next();编译是不会报错的,只有在运行时才会报错。

可以发现,如果不使用泛型:集合中添加的是Object类的对象,就会(1)涉及强制类型转换;(2)可向集合中添加任意类型的对象,存在风险;

为了避免上述问题:需要在创建Set的时候就制定Set中存入对象的类型:Set<Cat> set1 = new Set<Cat>();


泛型的使用语法:

(1)如  List<String> list = new ArrayList<String>();

(2)Java SE7及以后的版本中,构造方法中可以省略泛型类型,即也可以写作:  List<String> list = new ArrayList<>();


多态和泛型:

(1)错误示例:父类 Animal,子类Cat继承Animal类, List<Animal> list = new ArrayList<Cat>();这样写是错误的;即前后的类型必须要一致。

(2)List<Object> list = new ArrayList<String>();和 List<Number> numbers = new ArrayList<Integer>()也是错误的;前后的类型必须要一致,也就是变量声明的类型必须匹配传递给实际对象的类型

疑问:List<Animal> list = new ArrayList<Animal>();如果Cat是Animal的子类,Cat类型的对象可不可以存入list? 实测发现是可以的,但好像不提倡这么做。


1.泛型作为方法参数

父类:Goods类;

子类:Book类、Clothes类、Shoes类;

工具类:GoodsSeller类;

测试类:GoodsTest;

(注:(1)这其中也涉及了多态的应用;(2)核心是sellGoods(List<? extends Goods> goods)。)

public abstract class Goods {
	
	public abstract void sell();

}
public class Book extends Goods {

	@Override
	public void sell() {
		// TODO Auto-generated method stub
		System.out.println("Book类");
	}

}
public class Clothes extends Goods {

	@Override
	public void sell() {
		// TODO Auto-generated method stub
		System.out.println("Clothes类");

	}

}
public class Shoes extends Goods {

	@Override
	public void sell() {
		// TODO Auto-generated method stub
		System.out.println("Shoes类");

	}

测试类GoodsSeller,注意其     sellGoods(List<? extends Goods> goods)   的写法:

 注:(1)sellGoods(List<? extends 接口> 接口的实现类对象): 即extends后面也可以跟一个接口的。

            (2)sellGoods(List<? super Goods> goods):泛型参数可以是Goods或Goods的超类。)

public class GoodsSeller {
	
	public void sellGoods(List<? extends Goods> goods){
		// 遍历Set集合
		for(Goods g : goods){
			g.sell();
		}
	} 

}
public class GoodsTest {

	public static void main(String[] args) {
		
		List<Book> books = new ArrayList<Book>();
		books.add(new Book());
		books.add(new Book());
		List<Clothes> clothes = new ArrayList<Clothes>();
		clothes.add(new Clothes());
		clothes.add(new Clothes());
		List<Shoes> shoes = new ArrayList<Shoes>();
		shoes.add(new Shoes());
		shoes.add(new Shoes());
		
		GoodsSeller goodsSeller = new GoodsSeller();
		goodsSeller.sellGoods(books);
	}

}

以上写法是正确写法。

注:

(1)如果GoodsSeller类里,sellGoods方法参数如下时:

测试类里的方法调用会出错:

出现了上面的错误,如果把List<Book> books = new ArrayList<Book>();改成List<Goods> books = new ArrayList<Goods>();。不会报错,而且会正常执行。

但是,如果这样,books集合中也可以添加Clothes和Shoes类型的对象了,失去了泛型本来的意义。

所以为了根本解决这个问题,在测试类里面改成如上所示的:sellGoods(List<? extends Goods> goods) 就能解决:


2.【泛型作为方法参数】和【方法重载】的关联

这儿到底想表达什么,至今还不明白,,,,,。这是自定义泛型方法。

(1)一个新的写法:public <T extendx Number> void peintValue(T t):该方法的参数类型不仅可以是Number类型的,也可以是Number的子类类型的。这就是泛型之所以为型的意义吗?后续,需要在实际应用中继续加深对泛型的理解。这种写法,应该是自定义泛型了,下篇博客会讲到

相较于涉及泛型的方法,和具体类型的方法,实际调用时候,还是会选择更亲近的那一个。


3.?和T的区别

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值