2022-8-01 第七小组 黄均睿 学习日记 (day25)泛型、枚举

目录

泛型:

什么是泛型?

泛型的修饰:

泛型方法:

泛型的继承关系:

静态泛型方法

类型擦除:

泛型小结

枚举

枚举类型:

枚举:enum

大更新:

枚举的静态导入:

枚举的优势:

作业

总结 


从今天开始我们学的就是JavaSE高级部分:

  1. 泛型
  2. 枚举
  3. 多线程*(最难的,也是最重要的)
  4. 集合
  5. IO流
  6. 反射和注解
  7. 网络通信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牌的随机分发,今天是收获满满的一天。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值