Java基础

1.Java重要特点

  1. Java语言是面向对象的(oop)
  2. Java语言是健壮的。Java的强类型机制、异常处理、垃圾自动收集等是Java程序健壮性的重要保证
  3. Java语言是跨平台性的。(即:一个编译好的.class文件可以在多个系统下运行,这种特性称为跨平台)
  4. Java语言是解释型的。

解释型语言:javascript,PHP,java,不能直接被机器执行,需要解释器来执行,编译型语言,编译后的代码,可以直接被机器执行,C/C++。

2.什么是JDK、JRE

  • JDK基本介绍
  1. JDK的全称(Java Development Kit,Java开发工具包)

    JDK=JRE + java的开发工具[java,javac,javadoc,javap等]

  2. JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了JRE。

  • JRE基本介绍
  1. JRE(Java Runtime Environment,Java运行环境)

    JRE = JVM + Java的核心类库[类]

  2. 包含Java虚拟机(JVM JAVA Virtual Machine)和Java程序所需的核心类库等,如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。

3.注释

  • 单行注释: //
  • 多行注释:/**/

4.数据类型

在这里插入图片描述
String是引用类型,对String进行操作,是创建新的对象(String的操作都是改变赋值地址而不是改变值操作)。对StringBuffer进行操作,这是在原来的对象之上进行改变(StringBuffer的操作都是改变值得操作)

5.编码

ASCII码:使用一个字节对英语字符与二进制位之间得关系做了统一规定,一共规定了128个字符的编码,只占用了一个字节的后面7位,最前面的1位统一规定为0。缺点是但是不能表示所有字符。

Unicode:一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,使用Unicode没有乱码的问题。缺点是一个英文字母和一个汉字都占用2个字节,这对于存储空间来说是浪费。2的16次方是65536,所以最多编码是65536个字符。编码0-127的字符是与ASCII的编码一样,因此Unicode码兼容ASCII码。

UTF-8

  1. UTF-8是在互联网上使用最广的一种Unicode的实现方式(改进)
  2. UTF-8是一种变长的编码方式。它可以使用1-6个字节表示一个符号,根据不同的符号而变化字节长度
  3. 使用大小可变的编码 字母占1个字节,汉字占3个字节

6.基本数据类型转换

精度小的类型自动转换为精度大的数据类型,这个就是自动转换。(byte,short)和char之间不会相互自动转换,他们三者可以计算,在计算时首先转换为int类型。
在这里插入图片描述

  1. 基本类型转String
    语法:基本类型的值+""即可
int n1 = 100;
float n2 = 1.1f;
String str1 = n1 + "";
String str2 = n2 + "";
System.out.println(str1 + " " + str2) 
  1. String类型转基本数据类型
    语法:通过基本类型的包装类调用parseXX方法即可
Integer.parseInt("123");
Double.parseDouble("123.1");
Float.parseFloat("123.45");
Short.parseShort("12");
Long.parseLong("12345");
Boolean.parseBoolean("true");
Byte.parseByte("12");

7.逻辑运算符

&&具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式
在这里插入图片描述

8.原码反码补码

在这里插入图片描述

9.二维数组

栈里的引用指向堆里的两个引用。
在这里插入图片描述

10.对象内存布局

首先把类信息加载到方法区,主要是属性和行为,然后分配空间,根据属性不一样分配不同的空间,如果是字符串,分配一个地址再指向常量池,如果是基本数据类型直接放在堆,最后把地址返回给对象。
在这里插入图片描述
从main栈开始,调用一个方法就开辟一个新的栈,用完就销毁掉。
在这里插入图片描述

在这里插入图片描述

11.递归执行机制

每次调用递归方法开辟一个新的栈。
在这里插入图片描述
在这里插入图片描述

  • 例子一(老鼠出迷宫)
    在这里插入图片描述
public class MiGong {
    //编写一个main方法
    public static void main(String[] args){

        //思路
        //1.先创建迷宫,用二维数组表示 int[][] map = new int[8][7];
        //2.先规定map数组的元素值:0表示可以走,1表示障碍物
        int[][] map = new int[8][7];
        //3.将最上面的一行和最下面的一行,全部设置为1
        for(int i = 0; i < 7; i++){
            map[0][i] = 1;
            map[7][i] = 1;
        }

        //4.将最左边的一列和最右边的一列,全部设置为1
        for(int i = 0; i < 7; i++){
            map[i][0] = 1;
            map[i][6] = 1;
        }

        //剩余两个补齐
        map[3][1] = 1;
        map[3][2] = 1;

        //输出当前地图
        System.out.println("=============当前地图情况=============");
        for(int i = 0; i < map.length; i++){
            for(int j = 0; j < map[i].length; j++){
                System.out.print(map[i][j] + " ");
            }
            System.out.println();
        }


        T2 t2 = new T2();
        t2.find(map, 1, 1);

        //输出当前地图
        System.out.println("=============走迷宫后的地图情况=============");
        for(int i = 0; i < map.length; i++){
            for(int j = 0; j < map[i].length; j++){
                System.out.print(map[i][j] + " ");
            }
            System.out.println();
        }


    }
}

class T2 {
    //使用递归回溯的思想来解决老鼠出迷宫
    //1.findWay方法就是专门来找出迷宫的路径
    //2.如果找到,就返回ture,否则返回false
    //3.map表示迷宫,i,j表示老鼠位置,初始化为(1,1)
    //4.数字表示,0表示网格可走,1表示网格不可走,2表示网格走过,3表示走过不可走。
    //5.当map[6][5] == 2说明走通,结束
    public boolean find(int[][] map, int i, int j) {
        if (map[6][5] == 2){
            return true;
        } else {
            if (map[i][j] == 0) {
                map[i][j] = 2;
                if (find(map,i+1,j)) {
                    return true;
                }else if (find(map,i,j+1)){
                    return true;
                }else if(find(map,i-1,j)){
                    return true;
                }else if (find(map,i,j-1)){
                    return true;
                }else {
                    map[i][j] = 3;
                    return false;
                }
            }else {
                return false;
            }
        }

    }
}

  • 例子二(汉诺塔)
    在这里插入图片描述
public class HanoiTower {
    //编写一个main方法
    public static void main(String[] args) {
        T3 t3 = new T3();
        t3.move(3,'a','b','c');


    }
}

class T3 {
    //方法
    //num表示要移动的个数,a,b,c,分别表示A塔,B塔,C塔
    public void move(int num, char a,char b, char c) {
        //如果只有一个盘
        if (num == 1) {
            System.out.println(a + "->" + c);
        } else {
            //如果有多个盘。可以看成两个,最下面的和上面你的所有盘
            //1.先移动上面所有的盘到b,借助c
            move(num - 1, a, c, b);
            //2.把最下面的盘,移动到c
            System.out.println(a + "->" + c);
            //3.再把b上的所有盘移动到c,借助a
            move(num - 1, b, a, c);
        }
    }

}

在这里插入图片描述
递归调用流程图如下:
在这里插入图片描述

12.方法重载

定义:java中允许同一个类中,多个同名方法的存在,但要求形参列表不一致!重载可以减轻起名和记名的麻烦。

public class Overload {
    public static void main(String[] args) {
        T4 t4 = new T4();
        t4.m(1, 2, 3);
    }
}

class T4 {
    public void m (int n1, int n2) {
        System.out.println(n1+n2);
    }
    public  void m (int n1, double n2) {
        System.out.println(n1+n2);
    }
    public void m (int n1, int n2, double n3) {
        System.out.println(n1 + n2 + n3);
    }
}

13.可变参数

定义:java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。

  • 注意事项和使用细节
  1. 可变参数的试产可以为0个或任意多个
  2. 可变参数的实参可以为数组
  3. 可变参数的本质是数组
  4. 可变参数可以和普通类型的参数一起放在形参列表,但保证可变参数在最后
  5. 一个形参列表中只能出现一个可变形参
public class Overload {
    public static void main(String[] args) {
//        T4 t4 = new T4();
//        t4.m(1, 2, 3);
        HspMethod n = new HspMethod();
        System.out.println(n.sum());
    }
}

class HspMethod {
    //计算多个数的和
    //可以使用方法重载
    public int sum(int n1, int n2) {
        //2个数的和
        return n1 + n2;
    }
    public int sum(int n1, int n2, int n3) {
        //3个数的和
        return n1 + n2 +n3;
    }
    public int sun(int n1, int n2, int n3, int n4) {
        //4个数的和
        return n1 + n2 +n3 +n4;
    }
    //上面三个方法名称相同,功能相同,参数个数不同->使用可变参数优化
    //1.int...表示接收的是可变参数,类型是int,即可以接收多个int(0-多)
    //2.使用可变参数时,可以当作数组来使用,即nums可以当作数组
    public int sum(int... nums) {
        int sum = 0;
        System.out.println("接收的参数个数=" + nums.length);
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        return sum;
    }
}

14.作用域

  1. java编程中,主要的变量就是属性(成员变量)和局部变量。
  2. 局部变量一般是指在成员方法中定义的变量。
  3. java中作用域的分类
    全局变量:也就是属性,作用域为整个类体
    局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中!
  4. 全局变量(属性)可以不赋值,直接使用,因为有默认值,局部变量必须赋值后,才能用,因为没有默认值。

注意事项和细节使用
1.属性和局部变量可以重名,访问时遵循就近原则。
2.在同一个作用域中,比如在同一个成员方法中,两个局部变量不能重名。
3.属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。即在一次方法调用过程中。
4.作用域范围不同
全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
局部变量:只能在本类中对应的方法中使用
5.修饰符不同
全局变量/属性可以加修饰符
局部变量不可以加修饰符

15.构造器

定义:用类的一种特殊的方法,它的主要作用是完成对对象的初始化

规定:

  1. 构造器的修饰符可以默认
  2. 构造器没有返回值
  3. 方法名和类名必须一样
  4. 参数列表和成员方法一样的规则
  5. 构造器的调用,由系统完成

注意事项和使用细节:

  1. 构造器是完成对象的初始化,并不是创建对象
  2. 程序没有定义构造方法,系统会自动给类生成一个默认无参构造方法。
  3. 一旦定义了自己的构造器,默认的无参构造器就被覆盖了,就不能再使用默认的无参构造器,除非显式的定义一下。
public class Constructor {
    //编写一个main方法
    public static void main(String[] args) {
        Person1 p = new Person1("Ryan_小王", 23);
        System.out.println("姓名:" + p.name +"\n年龄:" + p.age);

        Person1 p2 = new Person1("小王");
        System.out.println("第二个构造器:" + "姓名:" + p2.name);
    }
}

class Person1 {
    String name;
    int age;

    //第一个构造器
    public Person1(String pName, int pAge) {
        name = pName;
        age = pAge;
    }

    //第二个构造器
    public Person1(String pName) {
        name = pName;
    }


}


16.对象创建的流程分析

在这里插入图片描述

17.this关键字

定义:java虚拟机会给每个对象分配this,代表当前对象。哪个对象调用,this就代表哪个对象。

public class Constructor {
    //编写一个main方法
    public static void main(String[] args) {
        Dog p = new Dog("小黄", 3);
        System.out.println("姓名:" + p.name +"\n年龄:" + p.age);
        System.out.println("对象的hashcode:" + p.hashCode());
        p.speak();
        System.out.println("===========================================");
        Dog p2 = new Dog("大黄", 4);
        System.out.println("姓名:" + p2.name +"\n年龄:" + p2.age);
        System.out.println("对象的hashcode:" + p2.hashCode());
        p2.speak();



    }
}

class Dog {
    String name;
    int age;
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("this的hashcode:" + this.hashCode());
    }
    public void speak() {
        System.out.println("I can speak!");
        System.out.println("this的hashcode:" + this.hashCode());
        //se
    }



}

结果表明:哪个对象调用,this就代表哪个对象。
this的hashcode:356573597
姓名:小黄
年龄:3
对象的hashcode:356573597
I can speak!
this的hashcode:356573597
===========================================
this的hashcode:1735600054
姓名:大黄
年龄:4
对象的hashcode:1735600054
I can speak!
this的hashcode:1735600054

在这里插入图片描述
this的注意事项和使用细节:

  1. this关键字可以用来访问本类的属性、方法、构造器
  2. this用于区分当前类的属性和局部变量
  3. 访问成员方法的语法:this.方法名(参数列表)
  4. 访问构造器语法:this(参数列表);注意只能在构造器中使用(即只能在构造器中访问另外一个构造器,必须放在第一条语句)
  5. this不能在类定义的外部使用,只能在类定义的方法中使用
//使用细节3代码研是
public class Constructor {
    //编写一个main方法
    public static void main(String[] args) {
        T1 t = new T1();
        t.eat();

    }
}


class T1 {
    public void speak() {
        System.out.println("hello");
    }

    public void eat() {
        System.out.println("eat");
        //第一种方式
        speak();
        //第二种方式
        this.speak();
    }
}

//使用细节4代码演示
public class Constructor {
    //编写一个main方法
    public static void main(String[] args) {
        T1 t = new T1();
        
    }
}

class T1 {
    public T1() {
        //这里去访问T(String name, int age)构造器
        this("jack", 200);
        System.out.println("T()构造器");
    }

    public T1(String name, int age) {
        System.out.println("T(String name, int age)构造器");
    }
}

18.IDEA快捷键

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

19.包

在这里插入图片描述
在这里插入图片描述

20.访问修饰符

在这里插入图片描述
在这里插入图片描述

21.面向对象编程三大特征之一:封装

定义:封装就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作[方法],才能对数据进行操作。

在这里插入图片描述
代码示例如下:

package com.xiaoming;

public class Person {
    public static void main(String[] args) {
        T t = new T();
        t.setName("小王");
        t.setAge(300);
        t.setSalary(30000);
        System.out.println(t.info());

        T t1 = new T("小彭sadasd",27,100);
        System.out.println(t1.info());

    }


}
class T {
    public String name;
    private int age;
    private int salary;

    public T() {

    }

    public T(String name, int age, int salary) {
//        this.name = name;
//        this.age = age;
//        this.salary = salary;
        setName(name);
        setAge(age);
        setSalary(salary);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        //加入业务逻辑
        if (name.length() >= 2 && name.length() <= 6) {
            this.name = name;
        } else {
            System.out.println("名字的长度必须在2-6之间");
        }

    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age > 0 && age <= 150) {
            this.age = age;
        } else {
            System.out.println("年龄必须在0-150之间");
        }

    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public String info() {
        return "姓名:" + name + "\t" + "年龄:" + age + "\t"+ "薪水" + salary;
    }
}


封装与构造器:为了不让防护机制失效,可以将set方法写入构造器。

    public T(String name, int age, int salary) {
//        this.name = name;
//        this.age = age;
//        this.salary = salary;
        setName(name);
        setAge(age);
        setSalary(salary);
    }

22.面向对象编程三大特征之一:继承

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
继承本质详解
代码如下所示:

package com.xiaoming;

public class ExtendTheory {
    public static void main(String[] args) {
        Son son = new Son();
        System.out.println(son.name);
    }

}

class GrandPa {
    String name = "爷爷";
    String hobby = "旅游";
}

class Father extends GrandPa {
    String name = "大头爸爸";
    int age = 39;
}

class Son extends Father {
    String name = "大头儿子";
}
//结果
大头儿子

访问规则
在这里插入图片描述
注意:若属性访问不到,可以通过父类提供的公共方法去访问。

内存加载机制
先在方法去加载类信息,从顶级父类开始加载,再在堆内分配内存,基本数据类型直接存,字符串常量放在常量池并返回地址,最终将对象地址返回到栈中 。在这里插入图片描述

23.super关键字

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

24.方法重写(override)

在这里插入图片描述

重载和重写的比较
在这里插入图片描述

25.面向对象编程三大特征之一:多态

  • 多态的基本介绍
    方法或对象具有多种形态。是面向对象的第三大特征,多态实建立在封装和继承基础之上的。

  • 多态的具体体现

    1.重写和重载就体现多态
    在这里插入图片描述
    2. 对象的多态(核心,困难,重点)
    (1)一个对象的编译类型和运行类型可以不一致
    (2)编译类型在定义对象时,就确定了,不能改变
    (3)运行类型是可以变化的
    (4)编译类型看定义时 =号的左边,运行类型看=号的右边
    在这里插入图片描述
    编译类型一直是Animal,运行类型从Dog变成了Cat。

Animal.java

package com.poly;

public class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Dog.java

package com.poly;

public class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }
}

Cat.java

package com.poly;

public class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }
}

Food.java

package com.poly;

public class Food {
    private String name;

    public Food(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Bone.java

package com.poly;

public class Bone extends Food {
    public Bone(String name) {
        super(name);
    }
}

Fish.java

package com.poly;

public class Fish extends Food{

    public Fish(String name) {
        super(name);
    }
}

Master.java

package com.poly;

public class Master {
    private String name;

    public Master(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    //主人给小狗喂骨头
    public void feed(Dog dog, Bone bone) {
        System.out.println("主人" + name + "给" + dog.getName() + "吃" + bone.getName());
    }

    //主人给小猫喂小黄鱼
    public void feed(Cat cat, Fish fish) {
        System.out.println("主人" + "给" + cat.getName() + "吃" + fish.getName());
    }
}

Poly.java

package com.poly;

public class Poly {
    public static void main(String[] args) {
        Master tom = new Master("汤姆");
        Dog dog = new Dog("大黄");
        Bone bone = new Bone("骨头");
        tom.feed(dog, bone);

        System.out.println("===================================");
        Cat cat = new Cat("小花猫");
        Fish fish = new Fish("小黄鱼");
        tom.feed(cat, fish);

    }
}

结果:
主人汤姆给大黄吃骨头
===================================
主人给小花猫吃小黄鱼

问题:如果有很多动物,很多种食物,就要在Master中重载很多feed()方法,多态的一种体现在对象的多态,可以对feed()进行如下操作:

//    //主人给小狗喂骨头
//    public void feed(Dog dog, Bone bone) {
//        System.out.println("主人" + name + "给" + dog.getName() + "吃" + bone.getName());
//    }
//
//    //主人给小猫喂小黄鱼
//    public void feed(Cat cat, Food fish) {
//        System.out.println("主人" + "给" + cat.getName() + "吃" + fish.getName());
//    }
  //使用多态机制,可以统一管理主人喂食的问题
  //animal编译类型实Animal,可以指向(接收)Animal子类的对象
  //food编译类型是Food,可以指向(接收)Food子类的对象
    public void feed(Animal animal, Food food) {
        System.out.println("主人" + name + "给" + animal.getName() + "吃" + food.getName());
    }

多态的向上转型

在这里插入图片描述

在这里插入图片描述

多态的向下转型

在这里插入图片描述
在这里插入图片描述

多态属性

AAA
属性

package com.poly;

public class Test{
    public static void main(String[] args) {
      //属性没有重写之说!属性的值看编译类型
		Base base = new Sub(); //向上转型
		System.out.println(base.count); //编译类型是Base,所以结果为10
    }
}

class Base { //父类
	int count = 10; //属性
}
class Sub extends Base { //子类
	int count = 20//属性

//结果
//10

instanceOf比较操作符

package com.poly;

public class Test2{
    public static void main(String[] args) {
      BB bb = new BB();
      //aa编译类型AA,运行类型是BB
      AA aa = new BB();
      System.out.println(bb instanceof BB); //true
      System.out.println(aa instanceof BB); //true,因为判断的是运行类型
    }
}

class Base {} //父类
class Sub extends Base {} //子类

练习题
在这里插入图片描述

动态绑定机制

在这里插入图片描述

package com.poly;

public class Test {
    public static void main(String[] args) {
        //运行类型是B
        A a  = new B();
        System.out.println(a.sum());
        System.out.println(a.sum1());
    }
}

class A {
    public int i = 10;

    public int sum() {
        return getI() + 10;
    }
    public int sum1() {
        return i + 10;
    }
    public int getI() {
        return i;
    }
}

class B extends A {
    public int i = 20;

   // public int sum() {
     //   return i + 20;
    //}
    //public int sum1() {
      //  return i + 10;
    //}
    public int getI() {
        return i;
    }
}
//B的sum和sum1两个方法未注释掉时候,输出结果为40,30
//注释掉B中的sum和sum1两个方法,输出结果为30,20
//原因:对象的方法会有动态绑定机制,而属性没有动态绑定机制,哪里声明,哪里使用,在子类B中未找到sum(),到A中找到了sum(),再使用B的getI() 得到i=20,返回20+10=30。

多态数组

Person[] person = new Person[5];
person[0] = new Person("Jack", 20);
person[1] = new Student("mary", 18, 100);
person[2] = new Student("smith", 19, 66);
person[3] = new Teacher("scott", 30, 20000);
person[4] = new Teacher("ryan", 23, 30000);

多态参数

在这里插入图片描述
Employee.java

package com.poly;

public class Employee {
    private String name;
    private double salary;

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    //得到年工资的方法
    public double getAnnual() {
        return 12 * salary;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

Worker.java

package com.poly;

public class Worker extends Employee {
    public Worker(String name, double salary) {
        super(name, salary);
    }

    public void work() {
        System.out.println("普通员工:" + getName() + "正在工作");
    }

    @Override
    public double getAnnual() { //因为普通员工没有其他收入,则直接调用父类方法
        return super.getAnnual();
    }
}

Manager.java

package com.poly;

public class Manager extends Employee {
    private double bonus;

    public Manager(String name, double salary, double bonus) {
        super(name, salary);
        this.bonus = bonus;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    public void manager() {
        System.out.println("经理" + getName() + "正在管理");
    }

    // 重写年薪方法
    @Override
    public double getAnnual() {
        return super.getAnnual() + bonus;
    }
}

PloyParameter.java

package com.poly;

public class PloyParameter {
    public static void main(String[] args) {
        Worker tom = new Worker("tom", 2500);
        Manager milan = new Manager("milan", 5000, 200000);
        PloyParameter e = new PloyParameter();
        e.showEmpAnnual(tom);
        e.showEmpAnnual(milan);
        e.testWork(tom);
        e.testWork(milan);



    }

    //实现获取任何员工对象的年工资,并在main方法中调用该方法[e.getAnnual()]
    public void showEmpAnnual(Employee e) {
        System.out.println(e.getAnnual());
    }

    //添加一个方法。testWork,若是普通员工,调用work(),若是经理,调用manage()
    public void testWork(Employee e) {
        if (e instanceof Worker) {
            ((Worker) e).work();
        } else if (e instanceof Manager) {
            ((Manager) e).manager();
        } else {
            System.out.println("不做处理!");
        }
    }
}

结果如下:

30000.0
260000.0
普通员工:tom正在工作
经理milan正在管理

26.Object类详解

1.==和equals的对比

  1. ==:既可以判断基本类型,又可以判断引用类型
  2. ==:如果判断基本类型,判断的是值是否相等。示例:int i = 10’ dpuble d =10.0;
  3. ==:如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象
  4. equals:是Object类中的方法,只能判断引用类型
  5. equals默认判断的是地址是否相等子类中往往重写该方法用于判断内容是否相等。【看看String和Integer的equals源代码】
    在这里插入图片描述

练习1:重写equals方法,判断两个对象内容是否相等,如果两个对象各个属性值都一样则返回true,反之false。

package com.poly;

public class Test2 {
    public static void main(String[] args) {
        Person tom = new Person("tom", 30);
        Person mike = new Person("tom", 30);
        System.out.println(tom.equals(mike));
    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public boolean equals(Object p) {
        //如果两个是同一个对象则直接返回true
        if (this == p) {
            return true;
        } else if (p instanceof Person) { //类型判断,是Person才比较
            //向下转型, 因为我们需要p的各个属性
            Person p1  = (Person) p;
            return  this.name.equals(p1.name) && this.age == p1.age;
        } else {
            return false;
        }
    }

}

练习2:==和equals判断

Person p1 = new Person();
p1.name = "xiaowang";

Person p2 = new Person();
p2.name = "xiaowang";

String s1 = new String("xiaowang");
String s2 = new String("xiaowang");

System.out.println(p1.equals(p2)); //false,因为Person没有重写equals,默认为Object的equals,直接比较两个对象是否相同

System.out.println(s1.equals(s2)); //true,String重写了equals,直接比较字符串的内容

System.out.println(p1.name.equals(p2.name)); //true,String重写了equals,直接比较字符串的内容

System.out.println(p1 == p2); // false,==的使用:基本类型判断值,引用类型判断地址即对象
System.out.println(s1 == s2); //false

练习3
在这里插入图片描述

2.hashcode方法

在这里插入图片描述
在这里插入图片描述

3.toString方法

在这里插入图片描述

4.finalize方法

在这里插入图片描述

package com.poly;

public class Test_GC {
    public static void main(String[] args) {
        Car bmw = new Car("宝马");
        bmw = null;
        System.gc(); //主动调用垃圾回收器
        System.out.println("程序退出!");

    }
}

class Car {
    private String name;

    public Car(String name) {
        this.name = name;
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("我们销毁汽车" + name);
        System.out.println("我们释放了某些资源。。。");
    }
    public void  say() {}

}

结果:
程序退出!
我们销毁汽车宝马
我们释放了某些资源。。。

27.断点调试

在这里插入图片描述
在这里插入图片描述

28.零钱通项目

1.面向过程版本

SmallChangeSys .java

package com.smallchangesys;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class SmallChangeSys {
    public static void main(String[] args) {
        //定义相关变量
        boolean loop = true;
        Scanner scanner = new Scanner(System.in);
        String key = "";

        //2.零钱通明细
        String details = "----------------零钱通明细--------------";

        //3.完成收益入账
        double money = 0;
        double balance = 0;
        Date date = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");//可以用于日期格式化的

        //4.消费
        String note = "";

        do {
            System.out.println("\n===========零钱通菜单===========");
            System.out.println("\t\t\t1 零钱通明细");
            System.out.println("\t\t\t2  收益入账");
            System.out.println("\t\t\t3 消费");
            System.out.println("\t\t\t4 退      出");

            System.out.println("请选择(1-4):");
            key = scanner.next();

            //使用switch分支控制
            switch (key) {
                case "1":
                    System.out.println(details);
                    break;
                case "2":
                    System.out.println("收益入账金额:");
                    money = scanner.nextDouble();
                    //money的值范围应该校验-》一会完善
                    balance += money;
                    //拼接收益入账信息到details
                    date = new Date(); //获取当前日期
                    details += "\n收益入账\t+" + money + "\t" + sdf.format(date) + "\t" + balance ;
                    break;
                case "3":
                    System.out.println("消费金额:");
                    money = scanner.nextDouble();
                    System.out.println("消费说明:");
                    note = scanner.next();
                    balance -= money;
                    //拼接消费信息到details
                    date = new Date();
                    details += "\n" + note +"\t-" + money + "\t" + sdf.format(date) + "\t" + balance;
                    break;
                case "4":
                    String choice = "";
                    while (true) {
                        System.out.println("你确定要退出吗? y/n");
                        choice = scanner.next();
                        if ("y".equals(choice) || "n".equals(choice)) {
                            break;
                        }
                    }
                    //当前用户退出while,进行判断
                    if (choice.equals("y")) {
                        loop = false;
                    }
                    break;
                default:
                    System.out.println("选择有误,请重新选择");
            }
        }while (loop);
    }
}

2.OOP版本

SmallChangeSysOOP .java

package com.smallchangesys;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class SmallChangeSysOOP {

    //定义相关变量
    boolean loop = true;
    Scanner scanner = new Scanner(System.in);
    String key = "";

    //2.零钱通明细
    String details = "----------------零钱通明细--------------";

    //3.完成收益入账
    double money = 0;
    double balance = 0;
    Date date = null;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");//可以用于日期格式化的

    //4.消费
    String note = "";

    //先完成显示菜单,并可以选择
    public void mainMenu() {
        do {
            System.out.println("\n===========零钱通菜单(OOP)===========");
            System.out.println("\t\t\t1 零钱通明细");
            System.out.println("\t\t\t2  收益入账");
            System.out.println("\t\t\t3 消费");
            System.out.println("\t\t\t4 退      出");

            System.out.println("请选择(1-4):");
            key = scanner.next();

            //使用switch分支控制
            switch (key) {
                case "1":
                    this.detail();
                    break;
                case "2":
                   this.income();
                    break;
                case "3":
                    this.pay();
                    break;
                case "4":
                   this.exit();
                    break;
                default:
                    System.out.println("选择有误,请重新选择");
            }
        }while (loop);

    }

    //完成零钱通明细
    public void detail() {
        System.out.println(details);
    }
    //完成收益入账
    public void income() {
        System.out.println("收益入账金额:");
        money = scanner.nextDouble();
        //money的值范围应该校验-》一会完善
        if (money <= 0) {
            System.out.println("收益入账金额应该大于0");
            return; //退出方法,不在执行后面的代码
        }
        balance += money;
        //拼接收益入账信息到details
        date = new Date(); //获取当前日期
        details += "\n收益入账\t+" + money + "\t" + sdf.format(date) + "\t" + balance ;
    }
    //完成消费
    public void pay() {
        System.out.println("消费金额:");
        money = scanner.nextDouble();
        System.out.println("消费说明:");
        note = scanner.next();
        balance -= money;
        //拼接消费信息到details
        date = new Date();
        details += "\n" + note +"\t-" + money + "\t" + sdf.format(date) + "\t" + balance;
    }
    //退出
    public void exit() {
        String choice = "";
        while (true) {
            System.out.println("你确定要退出吗? y/n");
            choice = scanner.next();
            if ("y".equals(choice) || "n".equals(choice)) {
                break;
            }
        }
        //当前用户退出while,进行判断
        if (choice.equals("y")) {
            loop = false;
        }
    }
}

测试类SmallChangeApp .java

package com.smallchangesys;

/**
 * 这里我们直接调用SmallChangeSysOOP对象,显示主菜单即可
 */
public class SmallChangeApp {
    public static void main(String[] args) {
        new SmallChangeSysOOP().mainMenu();
    }
}

29.类变量和类方法

1.类变量

定义:类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它的时,修改的也是同一个变量。

静态变量存储位置:JDK7以下版本静态域在方法区,JDK7以上版本,静态域存储于定义类型的Class对象中,Class对象如同堆中其他对象一样,存在于GC堆中。

共识
(1)static变量是同一个类所有对象共享
(2)static类变量,在类加载的时候就生成了

访问类变量
在这里插入图片描述
在这里插入图片描述
:类变量是随着类的加载而创建的,所以即使没有创建对象实例也可以访问。

类变量使用注意细节:
在这里插入图片描述
在这里插入图片描述

2.类方法

在这里插入图片描述

使用场景
在这里插入图片描述
注意事项
在这里插入图片描述
在这里插入图片描述

3.理解main方法

在这里插入图片描述
在这里插入图片描述
cmd中给main方法传参数
在这里插入图片描述
IDEA中给main方法传参在这里插入图片描述

30.代码块

1.代码块介绍

代码块相当于另外一种形式的构造器(对构造器的补充机制),可以做初始化操作,因为代码块的调用顺序优于构造器,会在构造器之前输出代码块内容,普通代码块创建对象时调用,创建一次,调用一次,静态代码块是类加载时执行,且只会执行一次,类加载有三种情况,第一种是对象实例时,第二种是创建子类对象实例时,父类也会被加载,第三种是使用类的静态成员时。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.代码块使用细节

1.静态代码块和普通代码块的加载,以及类加载的三种情况
在这里插入图片描述
2.创建一个对象,在一个类中的调用顺序,(静态代码块和静态属性初始化)->(普通代码块和普通属性的初始化)->(构造方法)
在这里插入图片描述
3.构造器的前面隐含了super()和调用普通代码块

4.创建子类对象(继承关系),静态代码块、静态属性初始化、普通代码块、普通属性初始化、构造方法的调用顺序
创建对象时候首先是类加载,会调用静态代码块和静态属性初始化,然后才是创建对象实例,这时候会调用构造方法,构造方法隐含了super()和调用普通代码块、普通属性初始化。
在这里插入图片描述

31.设计模式:单例模式

1.饿汉式
就是可能还没有用到对象的时候,随着类的加载,比如直接用类访问静态属性导致类的加载,这样就会致使对象创建好了,所以叫饿汉式。

package com.single_;

public class SingleTon01 {
    public static void main(String[] args) {
        GirlFriend gc = GirlFriend.getInstance();
        System.out.println(gc);
    }

}


//1.将构造器私有化,这样在别的类中就不能直接new一个对象
//2.在类的内部直接创建一个对象
//3.提供一个公共的static方法,返回gf对象,定义为static类型的原因是:若不是static就要new一个对象才能调用该方法
class GirlFriend {
    private String name;
    public static int i = 1;

    //1.将构造器私有化,这样在别的类中就不能直接new一个对象
    private GirlFriend(String name) {
    //    System.out.println("调用了");
        this.name = name;
    }

    //2.在类的内部直接创建一个对象
    private static GirlFriend gf= new GirlFriend("小红");

    //3.提供一个公共的static方法,返回gf对象
    public static GirlFriend getInstance() {
        return gf;
    }

    @Override
    public String toString() {
        return "GirlFriend{" +
                "name='" + name + '\'' +
                '}';
    }
}

2.懒汉式
懒汉式是在使用对象时才创建对象。

package com.single_;

public class SingleTon02 {
    public static void main(String[] args) {
        System.out.println(Cat.getInstance());
//        System.out.println(Cat.i);
    }
}

class Cat {
    private String name;
    public static int i = 1;
    private static Cat cat;
    //步骤
    //1.仍然构造器私有化
    //2.定义一个static静态属性对象
    //3.提供一个public的static方法,可以返回一个Cat对象
    private Cat(String name) {
//        System.out.println("调用了");
        this.name = name;
    }

    public static Cat getInstance() {
        if (cat == null) {
            cat = new Cat("小白");
        }
        return cat;
    }
    public String toString() {
        return "Cat{name='" + name + "'}";
    }
}

3.饿汉式和懒汉式区别
在这里插入图片描述

32.final关键字

1.基本介绍
在这里插入图片描述
2.注意事项
在这里插入图片描述
在这里插入图片描述
注:第七点中,若不用final修饰,调用Demo.i的时候会导致类的加载进而先执行静态代码块的内容,而在static前面加上final修饰的时候,再输出Demo.i的时候,就会直接输出结果,而不导致类加载。

33.抽象类

1.抽象类介绍
在这里插入图片描述
2.抽象类使用注意事项和细节讨论
在这里插入图片描述

package com.abstract_;

public class AbstarctDetail01 {
    //1.抽象类不能被实例化,此语句报错
    new A();
}

//2.抽象类不一定要有abstract方法,还可以有实现的方法
abstract class A {
    public void hi() {
        System.out.println("hi");
    }
}

//3.一旦包含了abstract方法,则这个类必须声明为abstract
abstract class B {
    public abstract void hi();
}

//4.abstract只能修饰类和方法,不能修饰属性和其它的
class C {
    // public abstract int n1 = 1; //这样是错误的
}

在这里插入图片描述

//7.如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,
//除非它自己也声明为abstract类
abstract class A {
    public abstract void hi();
}

//实现A的所有抽象方法,所谓实现方法,就是有方法体
class B extends A {
    @Override
    public void hi() {

    }
}

//自己也声明为抽象类
abstract  class C extends A { }

在这里插入图片描述

34.设计模式:抽象模板模式

计算不同job完成的时间。

1.Template.java

package com.abstract_;

abstract public class Template {
    public static void main(String[] args) {
        AA aa = new AA();
        aa.calculateTime();

        BB bb = new BB();
        bb.calculateTime();
    }
    
    public abstract void job();
    public void calculateTime() {
        //得到开始时间
        long start = System.currentTimeMillis();
        job();
        //得到结束时间
        long end = System.currentTimeMillis();
        System.out.println("执行时间:"+ (end - start));


    }

}

2.AA.java

package com.abstract_;

public class AA extends Template {
    @Override
    public void job() {
        int num = 0;
        for (int i = 0; i <= 10000; i++) {
            num += i;
        }
    }
}

3.BB.java

package com.abstract_;

public class BB extends Template {
    @Override
    public void job() {
        int num = 0;
        for (int i = 0; i <= 800000; i++) {
            num *= i;
        }
    }
}

35.接口

1.定义:接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。

类使用接口的时候必须实现接口的抽象方法,接口的方法默认为abstract修饰,在接口中abstract可写可不写。

小结:
1.在jdk7.0前,接口里的所有方法都没有方法体。即都是抽象方法。
2.Jdk8.0后接口可以有静态方法,默认方法(default修饰方法),也就是说接口中可以有方法的具体实现。
在这里插入图片描述

2.使用细节
在这里插入图片描述
在这里插入图片描述
课堂练习
在这里插入图片描述
3.接口和继承
在这里插入图片描述

package com.interface_;

public class Monkey {
    public static void main(String[] args) {
        LittleMonkey littleMonkey = new LittleMonkey("悟空");
        littleMonkey.m();
        littleMonkey.swimming();
        littleMonkey.fly();
    }
    public String name;

    public Monkey(String name) {
        this.name = name;
    }

    public void m() {
        System.out.println(name + "会爬树");
    }

    public String getName() {
        return name;
    }
}

//继承
class LittleMonkey extends Monkey implements A,B {
    public LittleMonkey(String name) {
        super(name);
    }

    @Override
    public void swimming() {
        System.out.println(getName() + "可以像🐟一样游泳。。。。");
    }

    @Override
    public void fly() {
        System.out.println(getName() + "可以像鸟一样飞翔。。。");
    }
}

//接口
interface A {
    void swimming();
}

interface B {
    void fly();
}

4.接口和抽象类

//定义接口,含有钻火圈方法
  public interface DrillFireCircle() {
      public abstract void drillFireCircle();
  }//定义抽象类狗类
  public abstract class Dog {
      public abstract void eat();
      public abstract void sleep();
  }
   
  //继承抽象类且实现接口
  class SpecialDog extends Dog implements drillFireCircle {
      public void eat() {
        //....
      }
      public void sleep() {
        //....
      }
      public void drillFireCircle() () {
        //....
      }
  }

继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如狗是否能钻火圈,能则可以实现这个接口,不能就不实现这个接口。

抽象类可以有不是抽象方法的方法,这样的类就不能算作纯粹的接口,只能说抽象类是普通类与接口之间的一种中庸之道。

接口与抽象类的不同之处在于
1、抽象类可以有方法体的方法,但接口没有。
2、接口中的成员变量隐式为 public static final,但抽象类不是的。
3、一个类可以实现多个接口,但只能继承一个抽象类。

4.接口多态传递
在这里插入图片描述

1.电脑Usb接口的案例体现多态

//1.interface_
package com.interface_;

public interface Interface_c {
    void start();
    void stop();
}

//2.Camera.java
package com.interface_;

public class Camera implements Interface_c {
    @Override
    public void start() {
        System.out.println("照相机开始拍照");
    }

    @Override
    public void stop() {
        System.out.println("照相机关闭拍照");
    }
}

//3.Phone.java
package com.interface_;

public class Phone implements Interface_c{
    @Override
    public void start() {
        System.out.println("手机开始拍照");
    }

    @Override
    public void stop() {
        System.out.println("手机关闭拍照");
    }
}

//4.Computer
package com.interface_;

public class Computer {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.use_c(new Camera());
        System.out.println("=========================" );
        computer.use_c(new Phone());
    }

    public void use_c(Interface_c interface_c) {
        interface_c.start();
        interface_c.stop();
    }
}

2.多态传递现象

package com.interface_;


public class InterfacePolyPass {
    public static void main(String[] args) {
        //接口类型的变量可以指向,实现了该接口的对象实例
        IG ig = new Teacher();
        //如果IG继承了IH接口,而Teacher类实现了IG接口
        //那么,实际上就相当于Teacher类也实现了IH接口
        //这就是所谓的多态传递现象
        IH ih = new Teacher();

    }
}

interface IH {}
interface IG extends IH{}

class Teacher implements IG {

}

36.内部类

在这里插入图片描述
在这里插入图片描述

1.局部内部类的使用

在这里插入图片描述

package com.innerclass;

public class innerclass01 {
    public static void main(String[] args) {
        Outer02 outer02 = new Outer02();
        outer02.m1();
    }
}

class Outer02 { //外部类
    private int n1 = 100;

    private void m2() {
        System.out.println("Outer02");
    } //私有方法

    public void m1() { //方法
        //1.局部内部类是定义在外部类的局部位置,通常在方法
        //3.不能添加访问修饰符,但是可以使用final修饰
        //4.作用域:仅仅在定义它的方法或代码块中
       final class Inner02 { //局部内部类(本质仍然是一个类)
            //2.可以直接访问外部类的所有成员,包含私有的
            public void f1() {
                //5.局部内部类可以直接访问外部类的成员
                System.out.println("n1=" + n1);
                m2();
            }
        }
        Inner02 inner02 = new Inner02();
        inner02.f1();

    }
}

2.匿名内部类

在这里插入图片描述
1.//基于接口的匿名内部类//演示基于类的匿名内部类

package com.innerclass;

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer04 outer04 = new Outer04();
        outer04.method();
    }
}

class Outer04 { //外部类
    private int i =10;
    public void method() { //方法
        //基于接口的匿名内部类
        //1.需求:想要使用IA接口,并创建对象
        //2.传统方法,是写一个类,实现接口,并创建对象
        //3.需要Tiger/Dog类只使用一次,后面再不使用
        //4.可以使用匿名内部类来简化开发
        //5.tiger的编译类型 ? IA
        //6.tiger的运行类型 ? 就是匿名内部类 Outer04$1
        //7.底层会分配Outer04$1对象
        /*
            class Outer04$1 implement IA {
                @Override
                public void cry() {
                    System.out.println("老虎叫唤。。。");
                 }
            }
         */
        IA tiger = new IA() {
            @Override
            public void cry() {
                System.out.println("老虎叫唤。。。");
            }
        };

        //7.jdk底层在创建匿名内部类Outer04$1,立即马上创建了Outer04$1实例,
        // 并把地址返回给了tiger
        //8.匿名内部类使用一次,就不能再使用,但对象还是可以一直调用的
        tiger.cry();
        tiger.cry();

        //演示基于类的匿名内部类
        //1.father编译类型Father
        //2.father运行类型Outer04$2
        //3.底层会创建匿名内部类
        /*
            class Outero4$2 extends Father{
              @Override
            public void test() {
                System.out.println("重写了父类的test()");
            }
           }
         */
        //4.同时也直接返回了匿名内部类Outer04$2的对象
        Father father = new Father("jack") {
            @Override
            public void test() {
                System.out.println("重写了父类的test()");
            }
        };
        System.out.println(father.getClass()); //Outer04$2
        father.test();
    }
}

interface IA { //接口
    public void cry();
}

class Father {
    private String name;

    public Father(String name) {
        this.name = name;
    }

    public void test() { //方法

    }
}

2.使用注意细节
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.匿名内部类实践
在这里插入图片描述

package com.innerclass;

public class InnerClassExercise01 {
    public static void main(String[] args) {
        //当做实参直接传递,简洁高效
        method(new A() {
            @Override
            public void say() {
                System.out.println("画画的baby");
            }
        });
        }
    //静态方法
    public static void method(A a) {
        a.say();
    }
}


//接口
interface A {
    void say();
}

在这里插入图片描述

package com.innerclass;

public class InnerClassExercise02 {
}

//接口
interface Bell {
    void ring();
}

class CellPhone {
    public static void main(String[] args) {
        CellPhone cellPhone = new CellPhone();
        //1.
        cellPhone.alarmclock(new Bell() {
            @Override
            public void ring() {
                System.out.println("懒猪起床了");
            }
        });

        //2.
        cellPhone.alarmclock(new Bell() {
            @Override
            public void ring() {
                System.out.println("小伙伴上课了。。");
            }
        });

    }
    public void alarmclock(Bell bell) {
        bell.ring();
    }
}


3.成员内部类

在这里插入图片描述

package com.innerclass;

public class MemberClass {
    public static void main(String[] args) {
        Outer05 outer05 = new Outer05();
        outer05.test();
    }
}

class Outer05 {
    public int i = 10;
    private  int age = 30;
    class Inner {
        public void say() {
            System.out.println("i = " + i + "\tage = " + age);
        }

    }
    public void test() {
        Inner inner = new Inner();
        inner.say();
    }
}

在这里插入图片描述
第6点举例说明如下在这里插入图片描述
在这里插入图片描述

4.静态内部类

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

37.枚举

1.自定义枚举

在这里插入图片描述
在这里插入图片描述

package com.enum_;

import java.util.Scanner;

/**
 * Created on 2021/6/18.
 *
 * @author Ryan_小王
 */
public class Enumeration01 {
    public static void main(String[] args) {
        System.out.println(Season.SPRING);
        System.out.println(Season.SUMMER);
        System.out.println(Season.AUTUNM);
        System.out.println(Season.WINTER);
    }

}

class Season {
    private String name;
    private String desc;

    private Season(String name, String desc) {
        this.name =name;
        this.desc =desc;
    }
    public final static Season SPRING = new Season("春天","温暖");
    public final static Season SUMMER = new Season("夏天","炎热");
    public final static Season AUTUNM = new Season("秋天","凉爽");
    public final static Season WINTER = new Season("冬天","寒冷");

    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}


2.enum枚举类

1.使用enum实现枚举类
2.public final static Season SPRING = new Season(“春天”,“温暖”);直接使用SPRING(“春天”,“温暖”)替代
3.如果有多个常量(对象),使用,号间隔即可
4.如果使用enum来实现枚举,要求将定义常量对象,写在前面

package com.enum_;

import java.util.Scanner;

/**
 * Created on 2021/6/18.
 *
 * @author Ryan_小王
 */
public class Enumeration01 {
    public static void main(String[] args) {
        System.out.println(Season.SPRING);
        System.out.println(Season.SUMMER);
    }

}

enum  Season {
    //1.使用enum实现枚举类
    //2.public final static Season SPRING = new Season("春天","温暖");
    //直接使用SPRING("春天","温暖")替代
    //3.如果有多个常量(对象),使用,号间隔即可
    //4.如果使用enum来实现枚举,要求将定义常量对象,写在前面
    SPRING("春天","温暖"),SUMMER("夏天","炎热");

    private String name;
    private String desc;

    private Season(String name, String desc) {
        this.name =name;
        this.desc =desc;
    }
//    public final static Season SPRING = new Season("春天","温暖");
//    public final static Season SUMMER = new Season("夏天","炎热");
//    public final static Season AUTUNM = new Season("秋天","凉爽");
//    public final static Season WINTER = new Season("冬天","寒冷");

    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

3.enum关键字实现枚举类注意事项

在这里插入图片描述
在这里插入图片描述

4.enum常用方法

在这里插入图片描述

package com.enum_;

/**
 * Created on 2021/6/18.
 *
 * @author Ryan_小王
 */
public class EnumMethod {
    public static void main(String[] args) {
        //使用Season枚举类,来演示各种方法
        Season summer = Season.SUMMER;
        //返回对象名
        System.out.println(summer.name());
        //输出该枚举对象的次序/编号,从0开始编号
        System.out.println(summer.ordinal());
        //含有定义的所有枚举对象
        Season[] values = Season.values();
        for (Season season: values) {
            System.out.println(season);
        }
        //valueof:将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则异常
        Season summer1 = Season.valueOf("SUMMER");
        System.out.println("summer1=" + summer1);
        //比较两个枚举常量的编号,此处为0-1=-1,所以结果为输出-1
        System.out.println(Season.SPRING.compareTo(Season.SUMMER));

    }
}

38注解

注解

39.异常

异常

40.常用类

1.包装类
2.Math类
3.Arrays类
4.String类
5.System类
6.BigInteger和BigDecimal类
7.日期类(Date、Catelendar、LocalDate)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值