泛型和项目

泛型和项目

1. 泛型
1.1 泛型体验卡
补充知识点 方法的重载

方法的重载 reload

  1. 要求在同一个类内,或者同一个接口内
  2. 要求方法名必须一致
  3. 要求方法形式参数必须不一致,调用方法的过程中通过
    实际参数列表数据类型,选择合适的方法

作用:

  1. 降低方法冗余
  2. 提供方法处理的多样性。
package com.qfedu.a_genericity;

public class Demo1 {
	public static void main(String[] args) {
		print(10);
		print(10.5);
		
	}
	
	/*
	 * 方法的重载 reload
	 * 	1. 要求在同一个类内,或者同一个接口内
	 *  2. 要求方法名必须一致
	 *  3. 要求方法形式参数必须不一致,调用方法的过程中通过
	 *  实际参数列表数据类型,选择合适的方法
	 *  
	 * 作用:
	 * 	1. 降低方法冗余
	 * 	2. 提供方法处理的多样性。
	 */
	public static void print(int num) {
		System.out.println("int类型:" + num);
	}

	public static void print(double num) {
		System.out.println("double类型:" + num);
	}
	
	public static void print(boolean ret) {
		System.out.println("boolean类型:" + ret);
	}
}

泛型第一个案例代码

public class Demo2 {
	public static void main(String[] args) {
		/*
		 * 方法形式参数列表数据类型 T 对应的具体数据类型,是由实际参数来决定的!!!
		 */
		print(10);
		print(false);
		print(10.5);
		print(10.5F);
	}
	
	/**
	 * 带有泛型约束的方法。
	 * 
	 * @param <T> 自定义泛型声明
	 * @param t   泛型对应类型
	 */
	public static <T> void print(T t) {
		System.out.println(t);
	}
}
1.2 泛型语法规则
泛型主要功能是为了增强【方法】
	1. 单一增强
	2. 批量增强(类和接口)
	
格式:
	<自定义无意义单一大写英文字母泛型占位符> 泛型声明
	常用占位符有
		<T> Type 类型
		<E> Element 元素
		<K> Key 键
		<V> Value 值
		<R> Return 返回值

泛型可以利用的到的位置:
	1. 泛型直接约束方法
	2. 泛型约束类,类内的成员方法可以使用类声明泛型
	3. 泛型约束接口,接口内成员方法可以使用接口声明泛型
1.3 自定义泛型约束方法

首先必须有泛型声明,告知编译器当前方法使用自定义泛型

格式:

​ 权限修饰符 是否静态 <泛型占位符> 方法名(形式参数列表)

【重点/注意】

形式参数列表中必须有一个参数对应自定义泛型,用于明确泛型对应的具体数据类型。

package com.qfedu.a_genericity;

public class Demo3 {
	public static void main(String[] args) {
		// 实际参数为 int 类型
		test(10);
		int i = getType(20);
		
		// 实际参数为 Demo3 类对象
		// 匿名对象直接作为方法的参数
		test(new Demo3()); 
		Demo3 d3 = getType(new Demo3());
		
		// 实际参数为 字符串类型
		test("字符串");
		String str = getType("字符串");
	}

	/**
	 * 方法参数使用了自定义泛型,泛型对应的具体数据类型由实际参数类型决定
	 * 
	 * @param <T> 自定义泛型声明
	 * @param t   泛型参数,利用用户提供的实际参数,约束泛型对应的具体数据类型。
	 */
	public static <T> void test(T t) {
		System.out.println(t);
	}

	/**
	 * 方法参数和返回值都使用了方法声明的自定义泛型,要求方法参数中的泛型参数约束 泛型对应具体数据类型
	 * 
	 * @param <T> 自定义泛型声明
	 * @param t   泛型参数,利用用户提供的实际参数,约束泛型对应的具体数据类型。
	 * @return 自定义泛型类型,泛型对应的具体数据类型由实际参数数据类型决定
	 */
	public static <T> T getType(T t) {
		return t;
	}
}

1.4 自定义泛型约束类 ==> 类中的方法
格式:
	class 类名<自定义泛型占位符> {
		成员变量 ==> 目前阶段不建议使用自定义泛型
		成员方法 ==> 【重点】泛型约束内容
		构造方法 ==> 目前阶段不建议使用自定义泛型
	}
	
	类名声明的自定义泛型用于成员方法使用数据类型约束。
package com.qfedu.a_genericity;

/**
 * 自定义类型,带有自定义泛型 <T>
 * 
 * 【注意】
 * 		一个类带有自定义泛型,泛型对应的具体数据类型,由实例化对象过程约束。
 * 		具体格式如下:
 * 			TypeA<String> t1 = new TypeA<String>();
 * 			
 * 			数据类型和构造方法方法名,之后都有一个尖括号明确数据类型,明确的数据类型就是用于
 * 			约束泛型对应的具体数据类型
 * 			目前 TypeA<String> t1 对象,所有的成员方法使用到自定义泛型的位置都是 String
 * 			t1 对象调用的方法
 * 				public void test(String t);
 * 				public String getType(String t);
 * 
 * 
 * @author Anonymous
 *
 * @param <T>
 */
class TypeA<T> {
	/**
	 * 成员方法,可以直接利用类名声明的自定义泛型,无需再次声明
	 * 
	 * @param t 自定义泛型
	 */
	public void test(T t) {
		System.out.println(t);
	}
	
	/**
	 * 成员方法,方法参数和返回值类型都是类名声明的自定义泛型
	 * 
	 * @param t 自定义泛型
	 * @return 自定义泛型
	 */
	public T getType(T t) {
		return t;
	}
	
	/*
	public static void testStatic(T t) {
		System.out.println(t);
	}
	*/
}

public class Demo4 {
	public static void main(String[] args) {
		// 实例化对象过程中,约束当前 TypeA t1 对象使用泛型对应具体数据类型为 String
		TypeA<String> t1 = new TypeA<String>();
		
		// 所有带有泛型 <T> 占位符对应的位置都是 String 类型
		t1.test("字符串");
		String str = t1.getType("字符串 String 类型");
		System.out.println(str);
	
		
		// 实例化对象过程中,约束当前 TypeA t2 对象使用泛型对应具体数据类型为 Integer <==> int 
		TypeA<Integer> t2 = new TypeA<Integer>();
		
		// 目前所有 t2 对象使用的方法泛型位置都是 Integer 类型 <==> int 类型
		t2.test(10);
		Integer i = t2.getType(100);
		System.out.println(i);
		
		// 实例化 TypeA 类对象,没有约束泛型对应的具体数据类型,Eclipse 有警告!!!
		// t3 对象的泛型对应什么类型??? 泛型所有位置都是 Object 类型
		TypeA t3 = new TypeA();
		
		/*
		 * 什么是 Object 类型
		 * 		Object 类型是 Java 中所有类型的父类,是 Java 最大数据类型。
		 * 		万物皆对象,万物皆 Object
		 * 
		 * 带有自定义泛型约束的类,没有在实例化对象过程中,明确泛型对应的具体数据类型,所有泛型
		 * 对应位置都是 Object 类型,这只是 Java 编译器的权宜之计,咱们开发禁止使用。
		 * 缺乏了数据类型明确,和数据类型一致化要求
		 */
		t3.test(1);
		t3.test('A');
		t3.test("Object");
		t3.test(new Demo4());
		
		Object o1 = t3.getType(10);
		Object o2 = t3.getType("字符串");
		
	}
}
思考题:
     就目前而言,TypeA 类中是否可以定义 static 修饰的静态成员方法,直接使用类名声明的自定义范???

1. 类名声明的自定义泛型什么时候明确约束对应的具体数据类型???
	实例化对象过程中约束
	
2. static 修饰的静态成员方法是在类文件加载阶段已经准备就绪,已具备执行能力。
	权限修饰符,静态标记,返回值类型,方法名,形式参数列表,方法体

3. static 如果可以使用类名声明的自定义泛型,存在一个问题
	在类加载阶段,泛型对应的具体数据类型不明确,无法使用。
	
	静态成员方法自定义声明泛型,自行使用,泛型对应的具体数据类型是由实际参数来约束的
	如果静态成员方法使用类名对应的自定义泛型,泛型需要在实例化对象过程中明确约束,和静态成员生命周期不统一

4. 类声明泛型需要实例化对象,但静态成员方法【没有对象】
1.5 自定义泛型约束接口 ==> 接口中的方法
格式:
	interface 接口<自定义泛型占位符>{
		成员变量 缺省属性: publi static final 要求定义是必须初始化
			final 关键字要求成员变量定义时必须初始化
			泛型在定义阶段没有明确的数据类型,无法进行合理合适的初始化
				【接口中成员变量无法使用自定义泛型】
		成员方法 缺省属性: public abstract 要求当前方法没有方法体
		default 修饰的默认方法: JDK 1.8 以上版本支持,允许方法有方法体
	}
	
语法总结:
	1. 接口中成员变量不能使用自定义泛型
	2. 接口中缺省属性为 public abstract 修饰方法和 default 修饰的方法类型都可以自定义泛型
/*
 * 1. 自由模式
 * 		泛型对应的具体数据类型由实现类自行决定
 * 2. 卑微模式
 * 		泛型对应的具体数据类型实现遵从接口的过程中直接约束。
 * */

/**
 * 自由模式
 * 	实现类声明和接口泛型一致的泛型占位符,有实例化对象过程对泛型数据类型进行约束和明确
 * */
class TypeB<T> implements A<T> {

	@Override
	public void test(T t) {
		// TODO Auto-generated method stub
		System.out.println(t);
	}
	@Override
	public T getType(T t) {
		return t;
	}
}

public class Demo5 {
	public static void main(String[] args) {
		//实例化 TypeB 对象,泛型约束为 String 类型
		TypeB<String> t1 = new TypeB<String>();
		/*
		 * t1 对象对应方法所有泛型位置都是 String 包括实现接口中的 public abstract 修饰方法
		 * 以及 接口中 default 关键字修饰的默认方法。
		 */
		t1.test("实现类遵从接口要求完成的放啊,参数泛型目前对应的为String 类型");
		t1.testDefault("接口中 default 修饰的默认方法,方法泛型对应的具体数据类型根据当前实例化 TypeB 对象 t1 明确为 String 类型");
		String string = t1.getType("实现类遵从接口要求完成的方法,方法参数和返回值类型对应泛型具体数据类型为 String 类型");
		System.out.println(string);
		/*
		 * t2 对象泛型约束为 Integer 类型,类内所有接口中缺省属性为 public abstract 方法实现和 default 默认方法
		 * 泛型对应具体数据类型都是 Integer 类型
		 */
		TypeB<Integer> t2 = new TypeB<Integer>();
		t2.test(10);
		t2.testDefault(2000);
		Integer i = t2.getType(1000);
	}
}

/**
 * 卑微模式
 * 	类遵从带有自定义泛型的接口,遵从过程中,接口直接明确泛型对应的具体数据类型。
 * 	接口实现类所有使用到泛型的位置都是接口明确约束的泛型类型
 * 
 * 
 * 
 * 当前TypeC 类泛型对应的具体数据类型为 Spring
 * 
 * 
 * 
 * */
class TypeC implements A<String> {

	@Override
	public void test(String t) {
		// TODO Auto-generated method stub
		System.out.println(t);
	}

	@Override
	public String getType(String t) {
		// TODO Auto-generated method stub
		return t;
	}
	
}


public class Demo6 {
	public static void main(String[] args) {
		TypeC t1 = new TypeC();
		t1.test("接口泛型在遵从过程中明确为String 类型");
		t1.testDefault("接口泛型在遵从过程中明确为 String 类型");
		
		
		String type = t1.getType("字符串");
		System.out.println(type);
	}
}

1.6总结
泛型
	1.泛型主要目的是增强方法,是满足方法数据类型支持的多样性,都是严格遵从数据类型一致化要求。
	一旦约束泛型对应具体的数据类型,数据类型无法修改!!
	2. 泛型在单一约束方法
		【明确要求】方法参数必须有一个对应自定义泛型类型
	3. 泛型在类声明使用
		【明确要求】泛型对应的具体数据类型由实例化过程约束,并且【强烈要求】必须约束!!不可以使用 Object
	4. 泛型在接口声明使用
		自由模式,实现类实例化对象约束
		卑微模式,实现类遵从接口,接口明确要求

“接口泛型在遵从过程中明确为 String 类型”);

	String type = t1.getType("字符串");
	System.out.println(type);
}

}


##### 1.6总结

泛型
1.泛型主要目的是增强方法,是满足方法数据类型支持的多样性,都是严格遵从数据类型一致化要求。
一旦约束泛型对应具体的数据类型,数据类型无法修改!!
2. 泛型在单一约束方法
【明确要求】方法参数必须有一个对应自定义泛型类型
3. 泛型在类声明使用
【明确要求】泛型对应的具体数据类型由实例化过程约束,并且【强烈要求】必须约束!!不可以使用 Object
4. 泛型在接口声明使用
自由模式,实现类实例化对象约束
卑微模式,实现类遵从接口,接口明确要求
















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值