1.2-static、final、权限关键字,代码块,接口,枚举

二 知识概要

  • 关键字

    • static 表示静态

    • 权限修饰符关键字

      public 公共的,protected 受保护的,缺省默认【package-private】包私有,private 私有的
      
    • final 修饰符关键字,表示最终,不可变的

  • 代码块

    构造代码块,静态代码块,局部代码块
    
    
  • 接口 interface

  • 枚举

三 课程内容

01 static关键字

学习目标
  • 能够定义静态变量和静态方法
  • 能够使用静态变量和静态方法
内容讲解
【1】static关键字介绍

含义:static表示静态

作用:可以去修饰成员变量,成员方法

被static修饰的额成员,称为类的成员(静态成员)。会随着类的加载而进入方法区内存,可以直接用类名调用。

没有被static修饰的成员,称为实例成员。实例成员必须要依赖对象去调用。

【2】静态变量和静态方法的定义

静态变量:

直接成员变量前加上static修饰即可。

静态方法:

直接在修饰符位置加上static即可

例如:

public class Student{
  public static String name;//静态变量
  
 
  public static void test1(){} //静态方法
}

【3】如何使用静态变量和静态方法

静态变量,静态方法的调用,可以使用两种方式调用:

  1. 直接用类名调用【最常见的,推荐的使用方式】
  2. 可以使用当前的类对象去调用。【不推荐的方式】
【代码实践】

定义一个学生类,里面定义实例成员,定义静态成员进行调用

public class Student {
    //实例变量
    public String name = "张三";
  
    //静态变量
    public static String schoolName = "黑马程序员";

    //实例方法
    public void study() {
        System.out.println(name + "在学习");
    }
    //静态方法
    public static void sleep() {
        System.out.println("同学在睡觉");
    }
}


测试类:

public class Demo01 {
    public static void main(String[] args) {
        //调用实例成分:一定要用对象调用
        Student stu = new Student();//实例(对象)
        System.out.println("stu.name = " + stu.name);
        stu.study();

        //调用类成分(静态成分):
        //直接类名调用【建议】
        System.out.println("Student.schoolName = " + Student.schoolName);
        Student.sleep();

        //直接用对象名调用
        System.out.println("stu.schoolName = " + stu.schoolName);
        stu.sleep();


    }
}

【4】static关键字使用注意
  • 静态变量:静态变量保存的值,可以被所有的本类对象所共享。(内存中只有一份数据)

    public class Demo02 {
        public static void main(String[] args) {
            Student s1 = new Student();
            s1.name = "李四";
            System.out.println("s1.name = " + s1.name);//李四
            s1.schoolName = "传智播客";
            System.out.println("s1.schoolName = " + s1.schoolName);//传智播客
    
            Student s2 = new Student();
            System.out.println("s2.name = " + s2.name);//张三
            System.out.println("s2.schoolName = " + s2.schoolName);//传智播客
    
        }
    }
    
    
    

    执行结果:

    s1.name = 李四
    s1.schoolName = 传智播客
    s2.name = 张三
    s2.schoolName = 传智播客
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AEMX6Qv5-1677809515411)(imgs/image-20201029095341304.png)]

  • 静态方法在类内部使用时,不能去访问非静态成分。

    静态成分会先于对象而存在,不能访问一个不存在的实例成分。

    静态方法只能直接访问静态成分。

    所以,main方法直接调用的方法或者成员,必须是静态成员。

​ 但是实例方法,既可以直接访问静态方法也可以直接访问非静态方法。

内容小结

static关键字表示什么含义?

表示静态

static关键字有什么作用?

可以修饰成员变量,成员方法,被static修饰的成员称为类成员(静态成员)

static关键字修饰的成员怎么调用?

  • 推荐使用类名调用
  • 也可使用对象名调用

静态变量有什么特点?

  • 共享,被所有该类所共享

静态方法调用成员有什么特点?

  • 只能调用静态成分。

02 权限修饰符关键字

学习目标
  • 理解四种权限的访问特点
  • 能够知道四种权限大小
内容讲解
【1】关键字介绍
publicprotected(空的)包私有private
同一类中
同一包中(子类与无关类)
不同包的子类
不同包中的无关类

权限大小的特点:

public > protected > 包私有【缺省】> private

【2】常见的一些使用
  • 类型的定义,用权限修饰符:public , 包私有

  • 成员变量,构造方法,成员方法:以实际要求而定

    比如:成员变量,要封装就得使用private关键字修饰

    构造方法:如果不想让别人创建对象,也可以使用private

内容小结

public:都可以访问

protected: 本类,本包中的类,其他包的子类

缺省包私有:本类,本包中的类

private:本类

03 final关键字

学习目标
  • 理解final关键字及其使用场景
内容讲解
【1】final关键字介绍

final关键字,是一种修饰符,被修饰的成分有一种最终,不可改变的特点。

可以修饰以下成分:

  1. 修饰类:该类就是一个太监类,不能被继承
  2. 修饰符方法:修饰的方法子类可以用,但是不能被覆盖重写
  3. 修饰变量:变量就不会改变,只能赋值一次。
内容小结

final:表示最终的不可变的

可以修饰:类,方法,变量

04 final修饰类

学习目标
  • 能够使用final定义最终类
  • 理解最终类的使用特点
内容讲解
【1】final修饰类的格式

在类的修饰符位置加上final关键字就可以

修饰符 final class 类名{
  
}

注意:abstract和final是否可以共存?不能共存

【2】使用特点

该类就不能有子类,就是一个最终类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cv2K9dyM-1677809515412)(imgs/image-20201029104217769.png)]

final class MyMath {
}

/*
class SubMath extends MyMath { //报错
}

class MyString extends String { //报错
}
*/

内容小结

如何定义final类?

在class前面加上final(在修饰符位置加上final)

final类特点?

不能被继承

05 final修饰方法

学习目标
  • 能够使用final定义最终方法
  • 理解最终方法的使用特点
内容讲解
【1】final修饰方法的格式

也是在修饰符位置加上final

修饰符 final 返回值类型 方法名(形参列表){
  方法体
}

注意:抽象方法能被final修饰么

【2】特点

不能被子类重写,但是可以被子类使用

代码实践

定义一个Animal类,写两个方法,一个是sleep最终方法,一个是eat方法。

定义子类Cat,测试是否可以使用并重写sleep和eat方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nHNjAzAB-1677809515413)(imgs/image-20201029105202487.png)]

public class Demo01 {
    public static void main(String[] args) {
        Cat c = new Cat();
        c.sleep();
        c.eat();

    }
}

class Animal {
    final public void sleep() {
        System.out.println("动物在睡觉~~");
    }

    public void eat() {
        System.out.println("吃东西");
    }
}

class Cat extends Animal {
    public void sleep() {//final不能重写
    }

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
        sleep();//可以使用父类的final方法
    }
}

内容小结

final修饰方法的格式?

  • 在返回值类型前加上final

final方法的特点?

  • 不能被子类重写,但是子类继承使用final方法

06 final修饰变量

学习目标
  • 能够使用final定义最终变量
  • 理解最终变量的使用特点
内容讲解
【1】final修饰变量的格式

在类型前加上final就可以了

【2】特点

变量的值只能赋值一次

【3】局部变量使用final修饰

不管是基本数据类型,还是引用数据类型,被final修饰的局部变量,其变量值是不能改变。

如果是引用数据类型,地址对应内存的数据是可以改变的。

代码演示

public class Demo01 {

    public static void main(String[] args) {
        //final修饰局部变量
        //基本数据类型
        int i1 = 10;
        i1 = 20;

        final int i2 = 30;
        //i2 = 40;

        //引用数据类型
        int[] arr1 = new int[10];
        arr1 = new int[20];

        final int[] arr2 = new int[5];
        //arr2 = new int[10];
        //引用数据类型对应地址内存中的数据是可以变化的
        arr2[0] = 10;
        arr2[0] = 20;

    }
}

【4】final修饰成员变量

格式:直接在类型前面的修饰符位置加上final就可以了

特点:

  1. 被final修饰的成员变量,称为常量是不能改变的
  2. 被final修饰的成员变量,一定要做唯一赋值【重点】
    • 直接赋值
    • 构造方法赋值

代码案例

class Student{
    public final String name="张三";//直接赋值

    public final int age;

    //public final int weight;

    //构造方法赋值,如果有多个重载的构造方法,所有构造方法都应该做初始化
    public Student(){
        age = 18;
    }

    public Student(int height,int age) {
        this.age = age;
    }

    //可不可以在普通方法中进行初始化
    /*public void setWeight(int weight) {
        this.weight = weight;
    }
*/
}


内容小结

如何给局部变量设置final,特点是什么?

  • 类型前加上final,只能赋值一次

如何给成员变量设置final,特点是什么?

  • 在类型前加上final,只能赋值一次,而且必须赋值。

final修饰的成员变量可以怎样赋值?

  • 直接赋值
  • 构造方法赋值

08 代码块

学习目标
  • 能够定义构造代码块,并知道执行特点
  • 能够定义静态代码块,并知道执行特点
  • 能够定义局部代码块,并知道执行特点
内容讲解
【1】构造代码块

格式:在类中方法外定义一个大括号

public class Student{
  {
    //构造代码块
  }
 
}

执行特点:会在每一个构造方法执行前,执行一次

作用:

  • 如果每个构造方法有重复的逻辑时,可以统一放到构造代码块中,比如给常量赋值

实例:

给final实例常量做赋值。(常量命名规范,一般会全大写,多个单词之间使用下划线分割)

public class Demo01 {
    public static void main(String[] args) {
        Student stu = new Student();

        Student stu2 = new Student(10);
    }
}

class Student {
    public final String SCHOOL_NAME;

    //借助构造代码块赋值
    {
        SCHOOL_NAME = "黑马";
        System.out.println("构造代码块执行");
    }


    public Student() {
        System.out.println("构造方法执行111");
    }

    public Student(int age) {
        System.out.println("构造方法执行222");

    }

}


执行结果:

构造代码块执行
构造方法执行111
构造代码块执行
构造方法执行222

【2】静态代码块

**格式:**直接在构造代码块上加上static

public class Student{
	static{
    //静态代码块
  }
}

执行特点:

随着类加载到内存,会执行一次。(类加载到方法区初始化的时候就会执行静态代码块)

作用:

可以对静态变量,或者常量进行初始化赋值

代码演示

定义一个数学工具类,要求里面存在静态常量PI,并且赋值为3.1415926。

工具类:不用创建对象,里面的成分都是静态的,使用时直接类名调用。

public class Demo01 {
    public static void main(String[] args) {
       // MyMath m = new MyMath();

        System.out.println("MyMath.PI1 = " + MyMath.PI1);
        System.out.println("MyMath.PI2 = " + MyMath.PI2);

        //MyMath.test();//方法要调用才会执行,静态代码块不用调用也会执行
    }
}


class MyMath{
    private MyMath(){}


    //静态常量PI
    public static final double PI1=3.1415926;
    public static final double PI2;

    static double PI3;

    static {//MyMath类加载到内存的时候就会执行,不需要调用
        //可以给静态成员(变量,常量)做初始化
        PI2 = 3.14;
        System.out.println("静态代码块执行");
        PI3 = 123;
    }

    public static void test() {
        System.out.println("静态方法");
    }

}

【3】局部代码块

怎么定义局部代码块?

  • **

    静态代码块,构造代码块
    方法中,构造方法中
    都可以定义局部代码块
    
    

    例如:

    class Student{
      static{
    		//静态代码块    
        
        {
          //局部代码块
        }
        
      }	
      
      {
        //构造代码块
         {
          //局部代码块
         }
      }
      
      public Student(){
        
        {
          //局部代码块
        }
        
      }
      
      
      public void test(){
        
        int a = 10;//局部变量
        {
          //局部代码块
        }
        
      }
      
      
    }
    
    

局部代码块作用?

为了限定变量的作用域。

找到包裹变量最近的一对大括号,从这个变量定义开始到右大括号都是该变量的作用域。

代码实例

public class Demo01 {
    public static void main(String[] args) {
        //System.out.println(i1); // 不在i1的作用域

        int i1 = 10;

        System.out.println(i1);

        {
            //局部代码块,限定局部变量的作用域
            int i2 = 20;

            System.out.println(i1);
            System.out.println(i2);
        }



        //System.out.println(i2); //不在i2的作用域,不能访问
        System.out.println(i1);
    }
}


内容小结
  • 构造代码块,怎么定义,执行特点,作用?

    在类中方法外定义的 { },每次构造方法执行前,执行一次。可以实例化实例成员。

  • 静态代码块,怎么定义,执行特点?

    在构造代码块前加上static,随着类加载而执行一次,可以用来初始化静态成分。

  • 局部代码块,怎么定义,作用?

    可以任何局部位置定义一个 { },限定了变量的作用域。

09 接口的定义

学习目标
  • 能够使用关键字interface定义接口
  • 理解接口中可以定义的成分
内容讲解
【1】接口介绍

接口也是一种引用数据类型。编译后也会得到class文件。

接口是一种抽象的类型,接口中可以定义方法和常量。接口是对一系列功能的抽取,和抽象类比较相似。

定义接口需要使用一个关键字:interface

interface关键字和class的等级是一样的。

定义类:
public class 类名{
  成员变量,成员方法,构造方法,常量
}

定义接口:
public interface 接口名{
  方法,常量
}

【2】接口中可以定义的方法

JDK8之前:抽象方法【重点】

JDK8开始:新增了默认方法和静态方法

JDK9开始:新增了私有方法

内容小结

定义接口的关键字? interface

接口中可以定义的成分?

  1. 常量
  2. 方法
    1. JDK8之前:抽象方法
    2. JDK8开始:默认方法+静态方法
    3. JDK9开始:私有方法

10 接口中常量的使用

学习目标
  • 能够定义并使用接口的常量
内容讲解

接口中常量的定义:

[public] [static] [final] 类型 常量名=;

使用方式:

直接使用接口名调用就可以

代码实践:

public class Demo01 {
    public static void main(String[] args) {
        //使用时,直接用接口名调用

        System.out.println("MyInterface.A = " + MyInterface.A);
        System.out.println("MyInterface.B = " + MyInterface.B);

        //MyInterface.B = 400; //常量值不能改变

    }
}

interface MyInterface {
    //常量定义
    public static final int A = 100;

    int B = 200;
}

内容小结

怎么定义接口的常量?

public static final 类型 常量名=;

怎么使用接口的常量?

接口名直接调用

11 接口的基本实现【重点】

学习目标
  • 能够使用implements关键字实现接口

  • 能够知道接口中抽象方法的使用

内容讲解
【1】接口的基本使用
  1. 接口本身是一种抽象的类型,接口不能直接实例化对象。
  2. 需要借助子类去实现(implements)接口,并重写所有的抽象方法。
  3. 子类如果不重写抽象方法,子类要变成抽象类。

类继承类:extends

类实现接口:implements

接口继承接口:extends

类实现接口的格式:

public class 类名 implements 接口1,接口2..{
  //如果有抽象方法,一定要实现所有的抽象方法
}


【2】含有抽象方法的接口使用

定义一个播放器的功能接口,含有功能 播放,暂停,停止。

public interface Player {
    //定义一个播放器的功能接口,含有功能 播放,暂停,停止。

    public abstract void play();

    void pause();

    void stop();

}

public class Demo01 {
    public static void main(String[] args) {

        //Player p = new Player();  //接口不能直接实例化对象

        Sony sony = new Sony();
        sony.play();
        sony.pause();
        sony.stop();


        Mp4Player mp4Player = new Mp4Player();
        mp4Player.play();
        mp4Player.pause();
        mp4Player.stop();
    }
}

abstract class Mp3Player implements Player {
    public String brand;
}

class Sony extends Mp3Player {

    @Override
    public void play() {
        System.out.println("索尼播放器:播放");
    }

    @Override
    public void pause() {
        System.out.println("索尼播放器:暂停");

    }

    @Override
    public void stop() {
        System.out.println("索尼播放器:停止");

    }
}

class Mp4Player implements Player {

    @Override
    public void play() {
        System.out.println("mp4播放");
    }

    @Override
    public void pause() {
        System.out.println("mp4暂停");

    }

    @Override
    public void stop() {
        System.out.println("mp4停止");

    }
}

内容小结

接口如何使用?

  • 可不可实例化?不行
  • 需要子类去实现接口,并重写(实现)所有的抽象方法

实现的关键字?

  • implements

12 接口中默认方法

学习目标
  • 能够定义接口中的默认方法
  • 能够使用接口中的默认方法
内容讲解

接口中的默认方法,是从JDK8开始新增的。

默认方法的定义格式:

借助关键字:default

[public] default 返回值类型 方法名(参数列表){
    //方法体
}

默认方法的使用:

子类实现接口后,子类可以直接使用默认方法,也可以重写默认方法。

代码实践

public interface Player {

    public default void play() {
        System.out.println("播放器在放电影");
    }
}


测试

public class Demo01 {
    public static void main(String[] args) {
        Mp4Player mp4 = new Mp4Player();
        mp4.play();


        Mp3Player mp3 = new Mp3Player();
        mp3.play();
    }
}
class Mp4Player implements Player {
}

class Mp3Player implements Player {
    //默认方法的逻辑不满足子类需要
    //重写

    @Override
    public void play() {
        System.out.println("Mp3在放音乐!!");
    }
}


内容小结

默认方法怎么定义?关键字:default

[public] default 返回值类型 方法名(参数列表){
  
}

默认方法怎么使用?

子类实现接口,子类可以直接使用默认方法,也可以重写使用

13 接口中静态方法

学习目标
  • 能够定义接口中的静态方法
  • 能够使用接口中的静态方法
内容讲解

静态方法定义格式:

[public] static 返回值类型 方法名(参数列表){
  方法体
}

注意:权限public可以省略不写。即使省略不写默认就是public

怎么使用静态方法?

直接使用接口名调用即可。

代码实践:

public class Demo01 {
    public static void main(String[] args) {
        //直接用接口名调用
        
        Player.play();

    }
}


interface Player{

    public static void play() {
        System.out.println("播放器播放音乐!");
    }
}

内容小结

静态方法怎么定义?

public static 返回值类型 方法名(参数列表){
  方法体
}

静态方法怎么使用?

直接使用接口名调用

14 接口中私有方法

学习目标
  • 能够定义接口中的私有方法
  • 能够使用接口中的私有方法
内容讲解

JDK9开始有私有方法。

私有方法定义格式:

权限修饰符放private进行修饰。

//私有非静态方法
private 返回值类型 方法名(参数列表){
  方法体
}

//私有静态方法
private static 返回值类型 方法名(参数列表){
  方法体
}

使用方式:

私有方法只能被本接口内部其他非抽象方法使用。也遵循静态方法只能访问静态成员。

代码实践:

interface Player{

    //抽象方法
    void test1();

    //默认方法
    default void test2(){
        test1();//抽象
        test2();//递归
        test3();//静态
        test4();//私有静态
        test5();//私有非静态
    }

    //静态方法
    static void test3() {
        //只能调用静态成分
        test3();//静态
        test4();//私有静态
    }
    //私有静态
    private static void test4() {

    }
    //私有非静态
    private void test5() {

    }
}

内容小结

私有方法怎么定义?

private 返回值类型 方法名(参数列表){ 
}

private static 返回值类型 方法名(参数列表){ 
}

私有方法怎么用?

只能被本接口中方法使用

15 接口多实现

学习目标
  • 能够掌握同时继承类及实现接口的格式
  • 能够理解多实现中抽象方法,默认方法,静态方法的特点
内容讲解
【1】继承实现的特点
  • 类支持单继承
  • 类实现接口,是支持多实现
  • 接口继承接口,是支持多继承
【2】接口多实现的语法格式
public class 类名 extends 父类 implements 接口1,接口2{
  
}

注意:如果要同时继承一个父类,及实现多个接口。一定要把继承放在实现的前面。

当一个类继承了一个父类,实现了多个父接口,子类就拥有父类及其父接口的相关成分。

【3】在多实现的时候,接口中方法的特点
  • 多个接口中存在多个抽象方法且存在相同的抽象方法

    子类要重写所有的抽象方法,如果是相同只要重写一次就可以
    
    
  • 多个接口中存在多个默认方法,且存在相同的默认方法【特殊】

    不冲突的默认方法,子类既可以直接使用,也可以重写使用
    但是如果有冲突相同的,子类就必须重写。
    
    
  • 私有方法,静态方法

    即使多个接口存在相同的,也不会对子类有影响
    
    

多实现,默认方法冲突演示

interface InterA {
    public default void test1() {
    }
}

interface InterB {
    public default void test1() {
    }

    public default void test2() {
    }

}

class C implements InterA, InterB {
    //如果父接口中存在相同的默认方法,子类必须重写
    @Override
    public void test1() {

    }
}

内容小结

继承类及实现接口的格式?

public classextends 父类 implements 接口1,接口2{
  
}
//先继承,后实现

多实现中,抽象方法,默认方法,静态方法私有方法的使用特点?

抽象方法:子类必须重写有抽象方法,如果有相同只要重写一次
默认方法:如果有冲突,必须重写。否则可以直接使用,也可以重写使用
静态及私有方法:对子类没有影响。

16 继承和实现优先级探索

学习目标
  • 能够知道父类和父接口中相同方法继承优先级
内容讲解
【1】父类和父接口的方法谁的优先级更高

存在类A继承了类B,同时实现了接口C。加入类B中存在一个方法和接口C中的方法签名一样(相同方法)。

子类对象调用该方法,会调用谁的方法?

public class Demo01 {
    public static void main(String[] args) {
        A a = new A();
        a.method();//这是来自父类的方法
    }
}

class A extends B implements C {
}

class B {
    public void method(){
        System.out.println("这是来自父类的方法");
    }
}

interface C {
    public default void method(){
        System.out.println("这是来自父接口的方法");
    }
}


执行结果:使用子类对象调用方法,执行的是父类的方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZltHM2M1-1677809515413)(imgs/image-20201029161903605.png)]

本质上,父类的方法会通过子类把父接口的相同方法给重写了。

内容小结

子类继承了父类和父接口,如果父类和父接口存在相同的方法。子类对象调用该相同的方法,优先执行父类的方法。

17 接口多继承

学习目标
  • 理解接口中多继承时各种方法的特点
内容讲解

接口的多继承思想,可以认为把多个接口的功能进行合并。

如果接口继承了多个父接口:

  • 抽象方法:抽象方法在子接口中可以重写,也可以不动。
  • 默认方法:如果多个接口中存在相同的默认方法,子接口要做强制重写。【特殊】
  • 私有,静态方法:对子接口没有关系,没有影响。

多继承中默认方法的特点:

interface A {
    public default void test1() {   }
}

interface B {
    public default void test1() {   }

    public default void test2() {    }
}

interface C extends A, B {
    //可以使用默认方法重写默认方法
    /*  @Override
      default void test1() {
      }*/

    //也可以使用抽象方法去重写父接口的默认方法
    void test1();

}

内容小结

接口的继承特点?

  • 接口可以多继承

接口继承使用什么关键字?

  • extends

接口的多继承中,方法有什么特点?

  • 抽象方法:可以重写,可以不动
  • 默认方法:如果有冲突的,子接口强制重写(默认方法重写,抽象方法重写)
  • 静态,私有方法:对子接口没有影响

18 接口的成分特点

学习目标
  • 能够知道接口中可以有什么不能有什么
内容讲解

接口只能有两种:

  • 方法
  • 常量
内容小结

接口中定义两种成分:方法+常量

19 抽象类和接口练习

学习目标
  • 能够区分抽象类和接口的使用
内容讲解

抽象类和接口有个共同点,都是抽象的类型,都不能直接实例化对象。

抽取的方式:

  • 事物的共性内容(属性,行为),抽取到父类中(抽象类)。
  • 特有的行为,可以抽取到接口中。

示例

​ 犬:

​ 行为:吼叫;吃饭;

​ 缉毒犬:

​ 行为:吼叫;吃饭;缉毒;

//抽象父类
public abstract class Dog{
  String name;
  int age;
  
  public abstract void wangwang();//吼叫
  
  public abstract void eat();//吃
}

//抽取接口
public interface JiDu{
  void jidu();
}


//金毛
public class JinMaoDog extends Dog{
  //重写抽象方法
}


public class JiDuDog extends Dog implements JiDu{
   //重写抽象方法
  
    public void jidu(){}
}


//其他事物

public class Pig implements JiDu{
   public void jidu(){}
}


接口弥补了Java中单继承的缺陷。

内容小结
  • 事物的共性内容(属性,行为),抽取到父类中(抽象类)。
  • 特有的行为,可以抽取到接口中。

20 枚举的定义和使用

学习目标
  • 能够定义枚举类型
  • 能够使用枚举中的常量
内容讲解

引用数据类型:数组,类,接口,枚举,注解

【1】枚举的定义

枚举类型作用:为了列举固定的,有限的数据。

定义格式:

关键字:enum (和class , interface 一样)

public enum 枚举{
  常量1,常量2;
}

例如:

定义一个枚举,用来列举性别

public class Demo01 {
    public static void main(String[] args) {
        Person p1 = new Person("张三", Sex.BOY);
        System.out.println(p1.name + "::" + p1.sex);
      
        Person p2 = new Person("李四", Sex.GIRL);
        System.out.println(p2.name + "::" + p2.sex);

        //枚举类型Sex,只能接收内部的BOY,GIRL两种值
        //Person p3 = new Person("王五", Sex.YAO);
    }
}
class Person {
    String name;
    //String sex;
    Sex sex;//枚举
    public Person(String name, Sex sex) {
        this.name = name;
        this.sex = sex;
    }
}

//定义一个枚举,用来列举性别
//枚举本质上也是一个类,枚举中定义的常量其实就是当前类型的对象
enum Sex {
    BOY, GIRL;
}


内容小结

枚举类型的使用场景?

  • 列举固定的有限的数据时。

枚举定义的格式?

public enum 枚举名{
  常量名1,常量名2;
}

使用时,直接用枚举名调用即可。

21 枚举的其他内容【了解】

学习目标
  • 理解枚举的本质是个类
  • 能够定义及使用枚举的成员变量,构造方法,成员方法
内容讲解
【1】枚举本质验证

JDK中有一个javap反编译命令,可以反编译字节码文件查看其本质:

javap -p 字节码文件名

final class Sex extends java.lang.Enum<_Sex> {
  public static final Sex BOY;
  public static final Sex GIRL;
  private static final Sex[] $VALUES;
  public static Sex[] values(); //将所有的枚举对象返回
  public static Sex valueOf(java.lang.String); //根据枚举的常量名字符串,转换为枚举对象
  private Sex();
  static {};
}


从反编译的结果:

  1. 枚举本质上就是最终类,而且继承了Enum类
  2. 定义的枚举常量,就是枚举类的对象。而且是静态的常量
  3. 有私有的构造方法【一定是私有的】
  4. 静态代码块
【2】枚举的其他成分定义

在枚举中定义:成员变量,构造方法,成员方法

假如要在枚举中添加其他成分,一定是在枚举常量之后添加。

格式:

public enum 枚举名{
  常量1,常量2;
  其他成分

}

在之间的Sex枚举类型上加上一个年龄属性,同时定义构造方法,成员方法

public class Demo01 {
    public static void main(String[] args) {
        //如果要调用枚举对象的成员,要先拿到枚举常量对象
        System.out.println(Sex.GIRL.getAge());//18
    }
}

enum Sex {
    YAO, //默认调用无参构造
    BOY(),   //调用无参参
    GIRL(18);//调用有参构造

    private int age;//成员变量

    private Sex() {
    }//构造方法一定是私有的

    Sex(int age) {
        this.age = age;
    }


    //成员方法
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

内容小结
  • 枚举的本质是一个类,可以使用javap命令进行反编译验证
  • 枚举中可以定义成员变量,成员方法,构造方法。
  • 注意:
    1. 定义的成分,一定要在常量之后
    2. 定义构造方法,一定是私有的

22 枚举的使用案例

学习目标
  • 能够知道什么时候使用枚举
  • 能够将性别,方向,季度,星期等定义成为枚举
内容讲解

什么时候使用枚举?

需要列举固定,有限的数据时,可以使用枚举来定义数据

练习:

性别

public enum Sex{
  BOY,GIRL;
}

方向

public enum Direc{
  UP,DOWN,LEFT,RIGHT;
}

季节

public enum Season{
  SPRING,SUMMER,AUTUMN,WINTER;
}

星期

public enum Week{
  MON,TUE,WEN,THE,FRI,SAT,SUN;
}

内容小结

什么时候使用枚举?

需要列举固定,有限的数据时,可以使用枚举来定义数据

小结

  • 能够定义和使用静态方法及静态变量

    使用static修饰成员变量,成员方法就是静态变量,静态方法

    使用静态成员,推荐使用类名调用

  • 能够说出final修饰类,方法,变量的特点

    final类:不能被继承

    final方法:不能被重写

    final变量:只能赋值一次

  • 能够说出4种权限修饰符的访问特点

    public > protected > 包私有 > private

  • 能够说出各种代码块的定义格式及执行特点

    构造代码块:类中方法外加上 {} ,会在每次构造方法执行前,执行一次

    静态代码块:在构造代码块加上static,会在类加载时执行一次

    局部代码块:局部位置加上 {}, 为了限定局部变量的作用域

  • 能够写出接口的定义格式

    关键字:interface

    public interface 接口{
      方法,常量
    }
    
    
  • 能够写出接口的实现格式

    关键字:implements

    public classimplements 接口1,接口2{
      //重写所有的抽象方法
    }
    
    
  • 能够说出接口中的成员特点

    只有常量和方法【重点掌握抽象方法】

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值