学习任务:

视频学习

定义泛型接口

实现类保持泛型

实现类传入具体类型

接口继承

小结

系统设计通常采用面向接口设计的方法 ,现在的需求是抽取一个通用的面向数组操作的接口,对数组元素存取需要支持不同的元素类型,在接口定义中可以使用泛型。

在接口定义中使用泛型的接口叫泛型接口,格式如下:

public interface 接口名<泛型标识符1,泛型标识符2...>{

}

下边是泛型接口PbList的定义,包括两个方法 如下:

package com.pbteach.javase.oop.generictypes2;

/**
 * 泛型接口测试
 * @author 攀博课堂(www.pbteach.com)
 *
 */
public interface PbList<T> {
	
	//添加元素
	int add(T obj);
	//根据索引获取元素
	T getByIndex(int index); 

}

接口实现类可以保留接口中定义的泛型,继续在实现类中使用泛型标识符,如下代码:

package com.pbteach.javase.oop.generictypes2;

/**
 * 泛型接口实现类
 * @author 攀博课堂
 * @version v1.0
 */
public class PbArrayList<T> implements PbList<T> {

	//数组用于存储各种对象
	private static Object[] objects;

	public PbArrayList(int size){
		objects = new Object[size];
	}
		
	/**
	 * 添加元素
	 * @param obj
	 * @return
	 * @author 攀博课堂
	 * @version v1.0
	 */
	@Override
	public int add(T obj) {
		for(int i=0;i<objects.length;i++) {
			if(objects[i] == null) {
				objects[i] = obj;
				return 1;
			}
		}
		return 0;
	}

	/**
	 * 获取元素
	 * @param index
	 * @return
	 * @author 攀博课堂
	 * @version v1.0
	 */
	@Override
	public T getByIndex(int index) {
		if(index>=0 && index<objects.length) {
			return (T) objects[index];
		}
		return null;
	}

}

测试时可以将接口实现对象向上转型为接口类型,测试代码如下:

package com.pbteach.javase.oop.generictypes2;

import com.pbteach.javase.oop.generictypes.PbCourse;
import com.pbteach.javase.oop.generictypes.PbStudent;

/**
 * 泛型接口实现类
 * @author 攀博课堂
 * @version v1.0
 */
public class PbArrayList<T> implements PbList<T> {
...
public static void main(String[] args) {
		PbArrayList<PbCourse> arrayList = new PbArrayList<PbCourse>(10);
		arrayList.add(new PbCourse(101L, "攀博课堂 java面向对象编程高级篇v1.0", 20F));
		arrayList.add(new PbCourse(102L, "攀博课堂 Spring Cloud 微服务开发v1.0", 50F));
		//由于getByIndex方法返回Object所以需要强制转换
		PbCourse course = arrayList.getByIndex(1);
		System.out.println(course.getCourseName());
		
		//传入学生类型
		PbArrayList<PbStudent> studentList = new PbArrayList<PbStudent>(10);
		studentList.add(new PbStudent(101L, "传智燕青", "1759102882@qq.com"));
		studentList.add(new PbStudent(102L, "攀博", "pbteach@126.com"));
		PbStudent student = studentList.getByIndex(1);
		System.out.println(student.getNickName());
}

上边例子中接口实现类继续保留泛型标识符T,当接口实现类无需使用泛型时则在定义时直接传入具体的类型,比如在实现接口时传入具体的类型为PbCourse,在实现接口方法时原来的变量T则更换为PbCourse具体类型,下边是例子代码:

package com.pbteach.javase.oop.generictypes2;

/**
 * 课程服务类
 * @author 攀博课堂
 * @version v1.0
 */
public class PbCourseList implements PbList<PbCourse>  {

	//数组用于存储各种对象
	private static PbCourse[] objects;

	public PbCourseList(int size){
		objects = new PbCourse[size];
	}
		
	/**
	 * 添加课程
	 * @param obj
	 * @return
	 * @author 攀博课堂
	 * @version v1.0
	 */
	@Override
	public int add(PbCourse obj) {
		for(int i=0;i<objects.length;i++) {
			if(objects[i] == null) {
				objects[i] = obj;
				return 1;
			}
		}
		return 0;
	}

	/**
	 * 获取课程
	 * @param index
	 * @return
	 * @author 攀博课堂
	 * @version v1.0
	 */
	@Override
	public PbCourse getByIndex(int index) {
		if(index>=0 && index<objects.length) {
			return objects[index];
		}
		return null;
	}

}

如下是测试代码,既然实现类没有使用泛型则在创建对象时就不用传递类型参数:

public static void main(String[] args) {
    PbCourseList courseList = new PbCourseList(10);
    courseList.add(new PbCourse(101L, "攀博课堂 java面向对象编程高级篇v1.0", 20F));
    courseList.add(new PbCourse(102L, "攀博课堂 Spring Cloud 微服务开发v1.0", 50F));
    PbCourse course = courseList.getByIndex(1);
    System.out.println(course.getCourseName());

}

泛型接口也可以被继承,子接口在继承父接口时可向父接口传入具体类型也可以保持泛型。

下边代码保持了父接口的泛型标识符,此时子接口就必须也有相同的泛型标识符。

package com.pbteach.javase.oop.generictypes2;

/**
 * 子接口继承父接口时使用泛型
 * @author 攀博课堂
 * @version v1.0
 */
public interface IPbCourseList1<T> extends PbList<T> {

	//删除元素
	int del(T obj);
}

如下代码在继承接口时指定具体类型:

package com.pbteach.javase.oop.generictypes2;

/**
 * 子接口继承父接口时传入具体类型
 * @author 攀博课堂
 * @version v1.0
 */
public interface IPbCourseList2 extends PbList<PbCourse> {

	//删除元素
	int del(PbCourse obj);
}

泛型接口定义格式如下:

public interface 接口名<泛型标识符1,泛型标识符2...>{

}

泛型接口实现时可传入具体类型也可以保持泛型。

传入具体类型
public class 类名 implements 接口名<具体类型>{

}
保持泛型
public class 类名<泛型标识符> implements 接口名<泛型标识符>{
	
}

泛型接口与泛型类一样都可以被继承。

public interface 子接口 extends 父接口<具体类型>{

}

public interface 子接口<泛型标识符> extends 父接口<泛型标识符>{

}
提问-攀博课堂
我要提问 不会就问,有效沟通
关注公众号,加入微信群交流提问。 攀博课堂官方公众号
问答列表,查看本知识点所有问题