目录
从今天开始我们学的就是JavaSE高级部分:
- 泛型
- 枚举
- 多线程*(最难的,也是最重要的)
- 集合
- IO流
- 反射和注解
- 网络通信Socke
泛型:
什么是泛型?
泛型:广泛的、普通的类型。
泛型能够帮助我们把【类型明确】的工作推迟到创建对象或者调方法的时候。
意思就是:我定义类的时候,我不需要考虑这个数组到底要存是那么类型。
泛型的修饰:
1.泛型类
2.泛型方法
3.泛型接口
泛型类把泛型定义在类上,这样用户在使用类的时候才能把类型确定。
具体使用方法:<>加上一个未知数。通常用大写字母(T K V)表示,实际上用啥都行,只要是个单词就可以。
public class A<T> {}
当我们在一个类后面加上了泛型<T>,这个T就是一个数据类型。
既然T就是一个数据类型,那我们就可以拿过来用
声明一个T类型的变量t:
private T t;
如果一个泛型类,在创建对象的时候没有指定泛型类型,默认还是Object,在使用这个类的时候,去确定泛型类型.
SuperArray<String> S=new SuperArray();//不规范,不要这么写
SuperArray<Employee> superArray=new SuperArray<>();
//在JDK7以后,可以省略等号右边的泛型的声明,<>必须得写,不写<>不规范。
SuperArray<Employee> superArray1=new SuperArray<Employee>();
泛型方法:
我们如果只关心某个方法,可以不定义泛型类。只定义一个泛型方法。
泛型方法是不是一定要在泛型类里?不是
泛型类里是不是一定要有泛型方法?也不是
在定义泛型方法时,要首先定义泛型类型。定义在方法中间,泛型的使用处之前
使用泛型方法,最好要结合返回值,和Object一样。
public <T> T show(T t){
// 拿着这个t在方法中做好多事情,再把t返回去
//调用另一个方法
System.out.println(t);
return t;
//也可以抛异常哟---不重要
}
泛型的继承关系:
1.父类是一个泛型类,子类要不要也是泛型类?
2.永远记住,泛型的声明只能在当前类名后或者方法中间,而且声明的泛型是自己的,和别人没有什么关系。
3.在子类继承父类时,子类泛型和父类泛型都写出来的情况下,父跟子
4.如果在继承时,没有写出任何泛型,当前子类就不是泛型类。是Object类
class Father<T>{
T t;
}
class Son<T> extends Father<T>{
//在确定子类泛型的某一时刻,你父类的泛型和子类一样。通过子类
}
class Son2 extends Father{ }
public class Test04 {
public static void main(String[] args) {
Son<Employee> stringSon=new Son<>();
stringSon.t=new Employee();
Son2 s=new Son2();
s.t.toString();
}
}
如果在一个泛型类中,尽量就不要在使用泛型方法。
泛型方法多数都是出现在非泛型类
静态泛型方法
1.静态方法如果是泛型方法,泛型的声明必须写。
2.因为静态结构是属于类的,不属于某个对象
interface Inter<T>{
<T> T show(T t);
static <T> T info(T t){
return t;
}
}
class Demo<T> implements Inter<T>{
@Override
public <T> T show(T t){
return t;
}
}
通配符:?代表上一个类/对象/属性/包的所有
类型擦除:
为了一些兼容性:使用到原始的类型(没有泛型),是可以的。
在泛型刚刚出现的时候,还是存在大量的不适用泛型的代码。
保证代码的兼容性,将参数化类型的实例传递给设计用于原始类型的方法必须合法的
为了保持兼容性:
在Java的泛型中,其实有一种类似的伪泛型,因为JAVA编译期间所有的泛型都会被擦掉
Java的泛型语法是在编译期这个维度上实现的。
正常来说在生成的字节码文件中卖不包含泛型的类型信息的。
在JVM中看到的只是SuperArray,由泛型附加的类型信息对JVM是看不到的
可以理解为,泛型的本质就是让程序员在编写代码时遵守的一个规则
比如SuperArray:在确定了泛型之后,在这个超级数组中就统一只放同一类型的
如果放入其他类型,编译不通过
1.泛型不能是基本数据类型。(原则上来说,数组可以作为泛型,语法角度,不可以)
<>里面放的就应该是类名。数组是在编译后才会生成一个类($xxxx)
2.方法重载:a.同一个类里 b.方法名相同 c.参数不同
原理:类型擦除。
3.多态上。
泛型的应用场景:
1.父类(接口),起到的是一个规范的作用,对里面的数据类型没有明确要求。
2.容器类。(超级数组,链表,队列,栈)
泛型小结
开发中,我们更多的是会使用到一些泛型类或泛型接口。
java的泛型语法是在编译期这个维度上实现的
正常来说在生成的字节码文件中,不包含泛型的类型信息
泛型的本质是让程序员写代码时遵守的一个规则
当类型无法确定,使用泛型
枚举
枚举类型:
应用场景:
在某些情况下,一个类的对象的个数是有限的,
如季节,春夏秋冬,比如24节气,星期等等...
规定这个类的对象的个数。
public class SeasonConstant {
public static final Integer SPRING=1;
public static final Integer SUMMER=2;
public static final Integer AUTUMN=3;
public static final Integer WINNER=4;
}
以前没有枚举的时候是这样写的
但是这样扩展很差。
枚举:enum
public enum Season {
private Integer value;
private String name;
private Season(){}
private Season(Integer value, String name) {
this.value = value;
this.name = name;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static final Season SPRING = new Season(1,"春天");
public static final Season SUMMER = new Season(2,"夏天");
public static final Season AUTUMN = new Season(3,"秋天");
public static final Season WINNER = new Season(4,"冬天");
}
大更新:
JDK5更新了枚举类
枚举类的命名规则:所有的枚举类要以Enum结尾。
枚举类中把需要用的到的对象声明出来
写对应的构造器,可以有set,get方法。
前面那些public static final 类名...太罗嗦,我可不可以删掉呢?可以:
这样写可以省略无参构造方法,
public enum SeasonEnum {
SPRING(1,"春天"),
SUMMER(2,"夏天"),
AUTUMN(3,"秋天"),
WINNER(4,"冬天");
private Integer value;
private String name;
SeasonEnum(Integer value, String name) {
this.value = value;
this.name = name;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
枚举的静态导入:
*号代表导入枚举类的所有对象:
import static com.jsoft.afternoon.SeasonEnum.*;
这样使用:(但一般不会导入。)
public class Ch04 {
public static void main(String[] args) {
System.out.println(SPRING.getName());
}
}
枚举的优势:
1.int类型不具备安全性。假如某个程序员在定义int时少写了个final,会存在被他人修改的风险。枚举类,它天然就是一个常量类
2.使用int类型,语义不够明确。
作业
4.1 案例介绍
使用54牌,打乱牌序,三个玩家参与游戏,三个交替摸牌,每个人17牌,最后三张底牌
4.2 案例分析
准备牌
牌可以设计成ArrayList<String>,每个字符串是一张牌,每张牌由花色数字两部分组成。我们可以for循环嵌套完成每张组装,
洗牌
Collections(工具类)里面shuffle方法进行随机排序,打乱牌序
发牌
将每个人以及底牌设计为ArrayList<String>先将3张牌作为底牌放到ArrayList集合中,其余对3取模依次发牌
看牌
将每个人及底牌,遍历查看
package morning;
import java.util.ArrayList;
import java.util.Collections;
public class ArrayListTest {
public static void main(String[] args) {
ArrayList userPoker = getUserPoker();
System.out.println("熊大:" + userPoker.get(0).toString());
System.out.println("熊二:" + userPoker.get(1).toString());
System.out.println("光头强:" + userPoker.get(2).toString());
System.out.println("底牌:" + userPoker.get(3).toString());
}
// 都有啥牌
public static ArrayList<String> getPoker(){
ArrayList<String> poker = new ArrayList<>();
String[] arr1 = new String[]{"♠","♦","♥","♣"};
String[] arr2 = new String[]{"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
poker.add("大王");
poker.add("小王");
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 13; j++) {
poker.add(arr1[i] + arr2[j]);
}
}
return poker;
}
public static ArrayList getUserPoker(){
// 创建玩家数组
ArrayList<ArrayList<String>> userArr = new ArrayList<>();
// 分四批
for (int i = 0; i < 4; i++) {
userArr.add(new ArrayList<String>());
}
// 54张牌
ArrayList<String> arrayList = getPoker();
// 打乱顺序
Collections.shuffle(arrayList);
// 一次发三张,共17轮d
for (int i = 0; i < 17; i++) {
for (int j = 0; j < 3; j++) {
// 玩家数组 发牌
userArr.get(j).add(arrayList.get(3 * i + j));
}
}
// 地主牌
for (int i = 51; i < 54; i++) {
userArr.get(3).add(arrayList.get(i));
}
return userArr;
}
}
输出结果:
熊大:[♣J, ♠2, ♥Q, ♥5, ♥K, ♥6, ♠10, ♥7, ♥10, ♣4, 小王, ♦4, ♠8, ♦10, ♣K, ♣7, ♠K]
熊二:[♠A, ♠J, ♣2, ♣6, ♣10, ♦7, ♣8, ♦3, ♦2, ♠7, ♠3, ♥4, ♥8, ♠5, ♦5, ♦J, ♦A]
光头强:[♥9, ♦9, ♣5, 大王, ♥A, ♦8, ♠Q, ♦Q, ♥2, ♦6, ♥3, ♣Q, ♣3, ♣A, ♠6, ♠4, ♣9]
底牌:[♥J, ♦K, ♠9]
总结
今天所学的泛型、枚举,由于昨晚的积极预习今天的知识点得到了很好的吸收。
我认为泛型——当一个数组中类型过多时,容易造成系统紊乱,泛型就很好的解决了这个问题,将所有类型统一在它的旗下,若不确定时则为object。
枚举——将可选项列出来,然后从中选择进行静态……操作进行修饰。
今天状态良好,晚上的在同学的帮助下了解了使用动态数组进行poker牌的随机分发,今天是收获满满的一天。