23.泛型让类型更加规范性

为什么使用泛型

在Java增加泛型之前,泛型程序设计使用继承来实现的,可其中也有不便,需要强制类型转换以及可向集合中添加任意类型的对象,存在一定的风险
因此使用泛型就是为了避免需要强制类型转换以及运行时异常的安全隐患,可以控制问题在编译时报错。

使用泛型

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

在Java SE7以后的版本中,构造方法中可以省略泛型类型

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

多态与泛型

变量声明的类型必须匹配传递给实际对象的类型
错误示例:

List<Object> list = new ArrayList<String>();
List<Number> list = new ArrayList<Ingeger>();

泛型作为方法参数

案例:

  • 定义一个抽象类Goods ,包含抽象方法sell()分别定义类Book、Clothes和Shoes继承Goods ,并实现sell()方法,输出一-句话,如:sell books
  • 定义一个商品销售类GoodsSeller ,模拟销售,包括方法:
    public void sellGoods(List <Goods> goods),循环调用List对象的sell()方法。
// 抽象类Goods 
public abstract class Goods {
	public abstract void sell();
}
// 实现类Book
public class Book extends Goods {
	@Override
	public void sell() {
		System.out.println("sell books");
	}
}
// 实现类Clothes 
public class Clothes extends Goods {
	@Override
	public void sell() {
		System.out.println("sell clothes");
	}
}
// 实现类Shoes 
public class Shoes extends Goods {
	@Override
	public void sell() {
		System.out.println("sell shoes");
	}
}

商品销售类GoodsSeller:

public class GoodsSeller {
	// 此处通过 List<? extends Goods> goods 的方式,规Goods和Goods的子类都可以添加,且限制类型的单一
	public void sellGoods(List<? extends Goods> goods) {
		// 遍历goods
		for(Goods g : goods) {
			g.sell();	// 调用sell方法
		}
	}
}

定义方法参照ArrayList构造方法:

规定E类与E的子类都可以传入,不仅可以extends类,也可以extends接口
在这里插入图片描述

同时还可以进行通过实现超类的声明:

// // 此处通过 List<? super Goods> goods 的方式,规定Goods和Goods的超类都可以添加,且限制类型的单一
public void sellGoods(List<? super Goods> goods){

}

测试类:

		List<Book> books = new ArrayList<>();
		books.add(new Book());
		books.add(new Book());
		books.add(new Book());
				
		GoodsSeller goodsSeller = new GoodsSeller();
		goodsSeller.sellGoods(books);

自定义泛型

定义泛型类1:(一种类型)

// T表示不确定什么类型
public class NumGeneric<T> {
	// 同样适用T代替
	private T num;
	public T getNum() {
		return num;
	}
	public void setNum(T num) {
		this.num = num;
	}
}

测试类:

		NumGeneric<Integer> intNum = new NumGeneric<>();
		intNum.setNum(10);
		System.out.println("Integer数为:" + intNum.getNum());
		
		NumGeneric<Float> intFloat = new NumGeneric<>();
		intFloat.setNum(3.1f);
		System.out.println("Float数为:" + intFloat.getNum());

通过自定义泛型,把数据类型参数化

定义泛型类2:(两种类型)

public class TowNumGeneric<T, X> {

	private T num1;
	private X num2;
	public void Num(T num1, X num2) {
		this.num1 = num1;
		this.num2 = num2;
	}
	public T getNum1() {
		return num1;
	}
	public void setNum1(T num1) {
		this.num1 = num1;
	}
	public X getNum2() {
		return num2;
	}
	public void setNum2(X num2) {
		this.num2 = num2;
	}
	
}

测试类:

		TowNumGeneric<Integer, Double> num = new TowNumGeneric<>();
		num.Num(20, 3.99);
		System.out.println("num1数为:" + num.getNum1());
		System.out.println("num2数为:" + num.getNum2());

自定义泛型方法

public class GenericMethond {
	// 不确定数据类型
	public <T> void printValue(T t) {
		System.out.println(t);
	}
	// 不确定数据类型,但必须是Number的子类
	public <T extends Number> void printNum(T t) {
		System.out.println(t);
	}
}

测试类:

		GenericMethond gm = new GenericMethond();
		gm.printValue("hello");
		gm.printValue(3.9f);
		gm.printValue(3);
		
		// printNum()里不可传字符串,必须是数值型
		gm.printNum(20);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空 白

停止的只会是自己,你得追逐世界

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值