Java学习笔记之泛型(二) 泛型的继承和实现

在上一篇文章Java学习笔记之泛型(一)泛型类、泛型方法、泛型接口中介绍了泛型的基本用法:泛型类、泛型方法和泛型接口,本文将讨论一下泛型的继承和实现的问题。

父类或者接口中定义的泛型可以被子类或者实现类继承过来吗?答案是肯定的。引深一下,如果父类或者接口中定义了多个泛型,那么子类或者实现类能否继承其中的一部分呢(或者说干脆就不继承了呢)?答案也是肯定的,子类或者实现类想继承几个泛型就继承几个泛型。那么再深入一下,在子类继承了父类的泛型基础上,子类自己能否再定义泛型呢?当然也是可以的。

首先我们定义一个父类,在父类里面定义了两个泛型T1和T2,并在构造方法中打印了其类型:

class Father<T1,T2>{
	T1 t1;
	T2 t2;
	public Father(T1 t1, T2 t2) {
		this.t1 = t1;
		this.t2 = t2;
		System.out.println("t1的类型是: " + t1.getClass());
		System.out.println("t2的类型是: " + t2.getClass());
	}
}

那么由上面的讨论,可以分为四种情况。

第一种情况:子类继承了父类所有的泛型。

public class Test {
	public static void main(String args[]) {
		Child1 child1 = new Child1<String, Integer, Float>("hahaha", 1, 1.0f);
	}
}

class Father<T1,T2>{
	T1 t1;
	T2 t2;
	public Father(T1 t1, T2 t2) {
		this.t1 = t1;
		this.t2 = t2;
		System.out.println("t1的类型是: " + t1.getClass());
		System.out.println("t2的类型是: " + t2.getClass());
	}
}

class Child1<T1,T2,T3> extends Father<T1,T2>{	
	private T3 t3;
	public Child1(T1 t1, T2 t2, T3 t3) {
		super(t1, t2);
		this.t3 = t3;
		System.out.println("t3的类型是: " + t3.getClass());
	}
}

在上述代码中,子类继承了父类的全部两个泛型T1和T2,除此之外子类还自己创建了一个泛型T3,运行结果如下:

在这里插入图片描述
第二种情况:子类只继承父类一部分泛型。

既然是子类继承了父类的一部分泛型,那么父类没被继承的泛型就需要在定义子类的时候将其类型确定了:

public class Test {
	public static void main(String args[]) {
		//Child1 child1 = new Child1<String, Integer, Float>("hahaha", 1, 1.0f);
		Child2 child2 = new Child2<Integer, Float>(1, "haha", 1.0f);
	}
}

class Father<T1,T2>{
	T1 t1;
	T2 t2;
	public Father(T1 t1, T2 t2) {
		this.t1 = t1;
		this.t2 = t2;
		System.out.println("t1的类型是: " + t1.getClass());
		System.out.println("t2的类型是: " + t2.getClass());
	}
}

class Child1<T1,T2,T3> extends Father<T1,T2>{	
	private T3 t3;	
	public Child1(T1 t1, T2 t2, T3 t3) {
		super(t1, t2);
		this.t3 = t3;
		System.out.println("t3的类型是: " + t3.getClass());
	}
}

class Child2<T1,T3> extends Father<T1,String>{	
	private T3 t3;	
	public Child2(T1 t1, String str, T3 t3) {
		super(t1, str);
		this.t3 = t3;
		System.out.println("t3的类型是: " + t3.getClass());
	}
}

在上面的代码中我们又新建了一个Child2类,它只继承了父类的一个泛型T1,T3是子类自己定义的一个泛型,父类的第二个泛型我们就要将它随便指定一个类型了。例子里面我们给他指定的是String,代码运行如下:
在这里插入图片描述
第三种情况:子类指定父类的所有泛型。

这种情况下子类不继承父类的泛型,那么在定义子类的时候要将父类的所有泛型都指定类型:

public class Test {
	public static void main(String args[]) {
		//Child1 child1 = new Child1<String, Integer, Float>("hahaha", 1, 1.0f);
		//Child2 child2 = new Child2<Integer, Float>(1, "haha", 1.0f);
		Child3 child3 = new Child3<Integer>(1, "haha", "xixixi");
	}
}

class Father<T1,T2>{
	T1 t1;
	T2 t2;
	public Father(T1 t1, T2 t2) {
		this.t1 = t1;
		this.t2 = t2;
		System.out.println("t1的类型是: " + t1.getClass());
		System.out.println("t2的类型是: " + t2.getClass());
	}
}

class Child1<T1,T2,T3> extends Father<T1,T2>{	
	private T3 t3;	
	public Child1(T1 t1, T2 t2, T3 t3) {
		super(t1, t2);
		this.t3 = t3;
		System.out.println("t3的类型是: " + t3.getClass());
	}
}

class Child2<T1,T3> extends Father<T1,String>{	
	private T3 t3;	
	public Child2(T1 t1, String str, T3 t3) {
		super(t1, str);
		this.t3 = t3;
		System.out.println("t3的类型是: " + t3.getClass());
	}
}

class Child3<T3> extends Father<String, String>{	
	private T3 t3;	
	public Child3(T3 t3, String str1, String str2) {
		super(str1, str2);
		this.t3 = t3;
		System.out.println("t3的类型是: " + t3.getClass());
	}
}

上面代码中我们新建了一个Child3类,同时指定了父类的泛型都为String,这时候子类只有一个泛型T3了(子类自己定义的泛型而不是继承来的)。
在这里插入图片描述

第四种情况:子类不指定父类泛型。

class Child4<T3> extends Father{	
	private T3 t3;	
	public Child4(Object obj1, Object obj2, T3 t3) {
		super(obj1, obj2);
		this.t3 = t3;
		System.out.println("t3的类型是: " + t3.getClass());
	}
}

这种情况跟第三种情况类似,子类也不从父类继承泛型,不同的是构造方法默认将父类泛型指定为Object,所以在主方法中实例化子类时候传什么参数都是可以的:

Child4 child41 = new Child4<Integer>("haha", "xixixi", 1);
Child4 child42 = new Child4<Integer>(1.0f, 2.0, 1);
Child4 child43 = new Child4<Integer>(1.0f, new Date(), 1);

这时Child4只有一个泛型T3,也就是它自己的泛型。

猜你喜欢

转载自blog.csdn.net/weixin_44965650/article/details/106955715