泛型--继承泛型

42280ff35d80a9fa4ba80a064ba6e694e83.jpg

package com.atguigu.javase.generic;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

// 自定义泛型类, A只能是类类型
class Person<A> { // A在这里表示它是某种类型, 类型的形参, 在本类中就可以直接使用A这个类型.
	// A类型在创建对象时指定.
	// 如果A类型在创建对象时,并未确定的指定, 它就是Object类型, 类型不安全了
	// 泛型类型隶属于对象的, 不同的对象在创建时指定的泛型类型可以不一样
	
	private String name;
	private A info;
	
	public Person() {
	}

	public Person(String name, A info) {
		super();
		this.name = name;
		this.info = info;
	}
	
	public void setInfo(A info) {
		this.info = info;
	}
	
	public A getInfo() {
		return info;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", info=" + info + "]";
	}
	
	/* 静态成员不可以使用泛型类型
	public static void test(A a) {
		
	}*/
	
	/**
	 * 泛型方法, 方法中的泛型类型在方法的返回值之前声明<泛型的类型参数>
	 * 泛型方法必须在形参中指定好特定的类型, 否则泛型方法中的泛型类型永远是Object
	 * 泛型方法中的泛型类型究竟是什么, 由实参来决定.所以是在方法的每一次调用时才能确定的.
	 * 如果实参是null, 则无法确定泛型类型, 只能是Object类型了.
	 * @return
	 */
	public <B> B testB(B b) {
		return null;
	}
}

class A<X> {
	X x;
	
	public X getX() {
		return x;
	}
}
class B extends A {} // 子类在继承时并未指定X的具体类型, 所以永远是Object
class C extends A<String> {} // 子类在继承时直接写死父类的泛型类型, 在子类中X类型永远是一致,不变的
class C2 extends A<Double> {}
class D<X> extends A<X> {} // 子类在继承父类时仍然保持泛型类型的不确定性.

public class GenericTest {
	
	@Test
	public void test6() {
		B b = new B();
		Object x = b.getX();
		
		C c = new C();
		String x2 = c.getX();
		
		D d = new D();
		Object x3 = d.getX();
		D<Integer> d2 = new D<Integer>();
		Integer x4 = d2.getX();
		String x5 = new D<String>().getX();
	}
	
	@Test
	public void test5() {
		List<Integer> list = new ArrayList<Integer>();
		for (int i = 0; i < 10; i++) {
			list.add((int)(Math.random() * 20));
		}
		System.out.println(list);
		
		Object[] array = list.toArray();
		for (Object object : array) {
			System.out.println(object);
		}
		
		System.out.println("**********************");
		
		Integer[] array2 = list.toArray(new Integer[] {});
		for (Integer integer : array2) {
			System.out.println(integer);
		}
	}
	
	@Test
	public void test4() {
		Person<String> person = new Person<String>("张三", "北京");
		Integer testB = person.testB(30);
		String testB2 = person.testB("男");
		Boolean testB3 = person.testB(false);
		Object testB4 = person.testB(null); // 当实参的类型无法确定时, 泛型方法中的类型就是Object
	}
	
	@Test
	public void test3() {
		List<Integer> list1 = new ArrayList<Integer>();
		List<Double> list2 = new ArrayList<Double>();
	}
	
	@Test
	public void test2() {
		// 在这个对象中的A类型就固定是String类型
		Person<String> person = new Person<String>("张三", "北京"); // String在创建对象时,会作为类中的A类型的具体类型
		String info = person.getInfo();
		System.out.println(info);
		
		//person.setInfo(30);
		
		//new Person<Integer>("李四", "上海");
		Person<Integer> person2 = new Person<Integer>("李四", 40);
		Integer info2 = person2.getInfo();
		System.out.println(info2);
	}
	
	@Test
	public void test1() {
		Person person = new Person("张三", 30); // 理论上A类型就是Integer了, 但是没有指定
		Object info = person.getInfo();
		System.out.println(info);
		person.setInfo("男"); // 在这里体现了类型不安全, 因为理论上类型是Integer,但是实际给定的是String
		
		Person person2 = new Person("李四", "女");
		Object info2 = person2.getInfo();
		System.out.println(info2);
	}
}	

c67777ab558099088b6263d0263c0c40e76.jpg

03dd31d728ad3b04fba28e200df46e42ae3.jpg

package com.atguigu.javase.generic;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.junit.Test;

public class GenericTest2 {
	
	public Comparable max(Collection<? extends Comparable> col) {
		Iterator<? extends Comparable> iterator = col.iterator();
		// 假设第1个数最大
		Comparable max = iterator.next();
		// 遍历所有数据, 如果某数据比最小值还小, 刷新最小值
		while (iterator.hasNext()) {
			Comparable next = iterator.next();
			if (next.compareTo(max) > 0) {
				max = next;
			}
		}
		return max;
	}
	
	public Comparable min4(Collection<? extends Comparable> col) {
		Iterator<? extends Comparable> iterator = col.iterator();
		// 假设第1个数最小
		Comparable min = iterator.next();
		// 遍历所有数据, 如果某数据比最小值还小, 刷新最小值
		while (iterator.hasNext()) {
			Comparable next = iterator.next();
			if (next.compareTo(min) < 0) {
				min = next;
			}
		}
		return min;
	}
	// 找出任意集合中的最大值
	@Test
	public void test8() {
		List<Integer> list = new ArrayList<Integer>();
		for (int i = 0; i < 10; i++) {
			list.add((int)(Math.random() * 20));
		}
		System.out.println(list);
		System.out.println(min4(list));
		
		Set<Integer> set = new HashSet<Integer>();
		for (int i = 0; i < 10; i++) {
			set.add((int)(Math.random() * 20));
		}
		System.out.println(set);
		System.out.println(min4(set));
		
		List<String> list2 = new ArrayList<String>();
		list2.add("xxx");
		list2.add("abc");
		list2.add("YYY");
		list2.add("123");
		list2.add("来点汉字");
		list2.add("你好");
		System.out.println(list2);
		System.out.println(min4(list2));
	}
	
	///
	
	public Number min3(Collection<? extends Number> col) {
		Iterator<? extends Number> iterator = col.iterator();
		// 假设第1个数最小
		Number min = iterator.next();
		// 遍历所有数据, 如果某数据比最小值还小, 刷新最小值
		while (iterator.hasNext()) {
			Number next = iterator.next();
			if (next.doubleValue() < min.doubleValue()) {
				min = next;
			}
		}
		return min;
	}
	
	@Test
	public void test7() {
		List<Integer> list1 = new ArrayList<Integer>();
		for (int i = 0; i < 10; i++) {
			list1.add((int)(Math.random() * 20));
		}
		System.out.println(list1);
		System.out.println(min3(list1));
		
		List<Float> list2 = new ArrayList<Float>();
		for (int i = 0; i < 10; i++) {
			list2.add((float)(Math.random() * 20));
		}
		System.out.println(list2);
		System.out.println(min3(list2));
		
		Set<Integer> set = new HashSet<Integer>();
		for (int i = 0; i < 10; i++) {
			set.add((int)(Math.random() * 20));
		}
		System.out.println(set);
		System.out.println(min3(set));
	}
	
	///
	
	public Number min2(List<? extends Number> list) {
		// 假设第1个数最小
		Number min = list.get(0);
		// 遍历所有数据, 如果某数据比最小值还小, 刷新最小值
		for (Number number : list) {
			if (number.doubleValue() < min.doubleValue()) {
				min = number;
			}
		}
		return min;
	}
	
	@Test
	public void test6() {
		List<Integer> list1 = new ArrayList<Integer>();
		for (int i = 0; i < 10; i++) {
			list1.add((int)(Math.random() * 20));
		}
		System.out.println(list1);
		System.out.println(min2(list1));
		
		List<Float> list2 = new ArrayList<Float>();
		for (int i = 0; i < 10; i++) {
			list2.add((float)(Math.random() * 20));
		}
		System.out.println(list2);
		System.out.println(min2(list2));
	}
	
	///
	
	// 写一个方法 double min(List<????> list) 
	public double min(List<? extends Number> list) {
		// 假设第1个数最小
		double min = list.get(0).doubleValue();
		// 遍历所有数据, 如果某数据比最小值还小, 刷新最小值
		for (Number number : list) {
			if (number.doubleValue() < min) {
				min = number.doubleValue();
			}
		}
		return min;
	}
	
	// 在测试方法中创建两个List集合, 一个保存随机整数, 另一个保存Float型随机数据
	@Test
	public void test5() {
		List<Integer> list1 = new ArrayList<Integer>();
		for (int i = 0; i < 10; i++) {
			list1.add((int)(Math.random() * 20));
		}
		System.out.println(list1);
		System.out.println(min(list1));
		
		List<Float> list2 = new ArrayList<Float>();
		for (int i = 0; i < 10; i++) {
			list2.add((float)(Math.random() * 20));
		}
		System.out.println(list2);
		System.out.println(min(list2));
	}
	
	public double avg(List<? extends Number> list) {
		double sum = 0;
		for (Number num : list) {
			sum += num.doubleValue();
		}
		return sum / list.size();
	}
	
	
	@Test
	public void test4() {
		List<Integer> list = new ArrayList<Integer>();
		for (int i = 0; i < 10; i++) {
			list.add((int)(Math.random() * 20));
		}
		System.out.println(list);
		System.out.println(avg(list));
		
		List<Double> list2 = new ArrayList<Double>();
		for (int i = 0; i < 10; i++) {
			list2.add((Math.random() * 20));
		}
		System.out.println(list2);
		System.out.println(avg(list2));
	}
	
	/*public int avg(List<Integer> list) {
	int sum = 0;
	for (Integer integer : list) {
		sum += integer;
	}
	return sum / list.size();
}*/
	
	@Test
	public void test3() {
		// 集合中保存的是Number类型及其未知父类   类型范围>= Number
		List<? super Number> list = new ArrayList<>();
		list.add(200); // 适合添加, 因为它里面可以保存至少是Number类型的对象
		list.add(2.5);
		
		Object object = list.get(0); // 不适合于获取, 因为是未知父类
		
		// 集合中保存的是Number类型及其未知子类类型, 类型范围 <= Number
		List<? extends Number> list2 = new ArrayList<>();
		//list2.add(200); // 不可以添加元素, 因为具体的子类类型是未知的. 不可以冒然添加元素
		//list2.add(2.8);
		Number number = list2.get(0); // 适合于获取, 因为最多就是Number. 
	}
	
	/**
	 * 此方法对于集合的访问是只读的, 更安全
	 * @param col
	 */
	public void travel(Collection<?> col) {
		for (Object object : col) {
			System.out.println(object);
		}
	}
	
	@Test
	public void test2() {
		List<Integer> list = new ArrayList<Integer>();
		for (int i = 0; i < 10; i++) {
			list.add((int)(Math.random() * 20));
		}
		travel(list);
	}
	
	@Test
	public void test1() {
		List<Integer> list1 = new ArrayList<Integer>();
		//List<Number> list2 = new ArrayList<Integer>(); // 原因是左侧的集合中保存的是范围更大的类型.
		// List<?>list 集合只能获取, 不能添加, 所以适用于只读访问.
		List<?> list2 = new ArrayList<Integer>(); // ?表示未知类型, 范围不确定
		//list2.add(100); // 绝对不可以... 因为集合中的类型未知, 不可以冒然添加
		//list2.add(new Object());
		list2.add(null); // 因为null不表示任何类型
		
		Object object = list2.get(0);
		
		List<Object> list3 = new ArrayList<Object>();
		list3.add(200);
	}
}

 

转载于:https://my.oschina.net/architectliuyuanyuan/blog/3055274

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值