抽象类,接口、final关键字、单例设计模式、枚举



《抽象类》


我认为的定义:

  • 拥有抽象方法的类就是抽象类。
  • 抽象方法:是只有方法签名没有方法体,必须用abstract修饰。
  • 抽象类本身也要用abstract修饰的,作用是让子类继承,子类一定要重写抽象方法。
  • 模板思想,设计模板模式。
  • 1.1 概述

1.1.1 抽象类引入

父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了(因为子类对象会调用自己重写的方法)。换句话说,父类可能知道子类应该有哪个功能,但是功能具体怎么实现父类是不清楚的(由子类自己决定),父类完全只需要提供一个没有方法体的方法签名即可,具体实现交给子类自己去实现。我们把没有方法体的方法称为抽象方法。Java语法规定,包含抽象方法的类就是抽象类

  • 抽象方法 :没有方法体的方法。
  • 抽象类:包含抽象方法的类。

1.2 abstract使用格式

abstract是抽象的意思,用于修饰方法方法和类,修饰的方法是抽象方法,修饰的类是抽象类。

1.2.1 抽象方法

使用abstract 关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。

定义格式:

修饰符 abstract 返回值类型 方法名 (参数列表);

代码举例:

public abstract void run();

1.2.2 抽象类

如果一个类包含抽象方法,那么该类必须是抽象类。注意:抽象类不一定有抽象方法,但是有抽象方法的类必须定义成抽象类。

定义格式:

abstract class 类名字 { 


}

代码举例:

public abstract class Animal {
public abstract void run();
}

1.2.3 抽象类的使用

要求:继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。

代码举例:

// 父类,抽象类
abstract class Employee {
private String id;
private String name;
private double salary;


public Employee() {
  }


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


// 抽象方法
// 抽象方法必须要放在抽象类中
abstract public void work();
}


// 定义一个子类继承抽象类
class Manager extends Employee {
public Manager() {
  }
public Manager(String id, String name, double salary) {
super(id, name, salary);
  }
// 2.重写父类的抽象方法
@Override
public void work() {
    System.out.println("管理其他人");
  }
}


// 定义一个子类继承抽象类
class Cook extends Employee {
public Cook() {
  }
public Cook(String id, String name, double salary) {
super(id, name, salary);
  }
@Override
public void work() {
    System.out.println("厨师炒菜多加点盐...");
  }
}


// 测试类
public class Demo10 {
public static void main(String[] args) {
// 创建抽象类,抽象类不能创建对象
// 假设抽象类让我们创建对象,里面的抽象方法没有方法体,无法执行.所以不让我们创建对象
//    Employee e = new Employee();
//    e.work();


// 3.创建子类
    Manager m = new Manager();
    m.work();


    Cook c = new Cook("ap002", "库克", 1);
    c.work();
  }
}

tips:此时的方法重写,是子类对父类抽象方法的完成实现,我们将这种方法重写的操作,也叫做实现方法


1.3 抽象类的特征

抽象类的特征总结起来可以说是 有得有失

有得:抽象类得到了拥有抽象方法的能力。

有失:抽象类失去了创建对象的能力。

其他成员(构造器,实例方法,静态方法等)抽象类都是具备的。

1.4 抽象类的注意事项

关于抽象类的使用,以下为语法上要注意的细节,虽然条目较多,但若理解了抽象的本质,无需死记硬背。

  1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。
  2. 抽象类中,可以有构造器,是供子类创建对象时,初始化父类成员使用的。理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。
  3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。
  4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则子类也必须定义成抽象类,编译无法通过而报错。理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。
  5. 抽象类存在的意义是为了被子类继承,抽象类体现的是模板思想。理解:抽象类中已经实现的是模板中确定的成员,抽象类不确定如何实现的定义成抽象方法,交给具体的子类去实现。

1.5 抽象类存在的意义(为什么会有抽象类)

(1)被继承,抽象类就是为了被子类继承,否则抽象类将毫无意义。(核心意义)
(2)抽象类体现的是"模板思想":部分实现,部分抽象。
    -- 可以使用抽象类设计一个模板模式。

那么什么是模板(设计)模式呢?

是前人(技术大牛,一些官方协会或者一些知名的IT公司)已经研发好或者设计好的优秀软件设计思想,后来者可以直接使用就能够得到很好的软件模式。

模板模式的优点就是:部分实现,部分抽象,可以简化功能代码,提高开发效率。

就比如我们写一个作文它也会有模板:标题和第一段以及最后一段是固定的,正文部分交给使用模板的人自己去实现。

比如我们现在使用抽象类设计一个模板模式的应用,例如在小学的时候,我们经常写作文,通常都是有模板可以套用的。假如我现在需要定义新司机和老司机类,新司机和老司机都有开车功能,开车的步骤都一样,只是驾驶时的姿势有点不同,新司机:开门,点火,双手紧握方向盘,刹车,熄火老司机:开门,点火,右手握方向盘左手抽烟,刹车,熄火。我们可以将固定流程写到父类中,不同的地方就定义成抽象方法,让不同的子类去重写,demo如下:

// 司机开车的模板类
public abstract class Driver {
    public void go() {
        System.out.println("开门");
        System.out.println("点火");
        // 开车姿势不确定?定义为抽象方法
        ziShi();
        System.out.println("刹车");
        System.out.println("熄火");
    }


    public abstract void ziShi();
}

现在定义两个使用模板的司机:

public class NewDriver extends Driver {


    @Override
    public void ziShi() {
        System.out.println("新司机双手紧握方向盘");
    }
}


public class OldDriver extends Driver {
    @Override
    public void ziShi() {
        System.out.println("老司机右手握方向盘左手抽烟...");
    }
}

编写测试类

public class Demo02 {
    public static void main(String[] args) {
        NewDriver nd = new NewDriver();
        nd.go();


        OldDriver od = new OldDriver();
        od.go();
    }
}

可以看出,模板模式的优势是,模板已经定义了通用架构,使用者只需要关心自己需要实现的功能即可!非常的强大!


接口


1,什么是接口呢?

接口是更加彻底的抽象,接口中全部是抽象方法和常量,(JDK1.8之前)

2,接口有啥用?

接口体现的是规范思想,实现接口的类必须重写完接口中全部的抽象方法。

规范 == 约束。

2.2 定义格式

//接口的定义格式:
修饰符 interface 接口名称{
    // 抽象方法
}


// 修饰符:public|缺省
// 接口的声明:interface
// 接口名称:首字母大写,满足“驼峰模式”

tips:接口是更加彻底的抽象,接口中全部是抽象方法。(JDK8之前),接口同样是不能创建对象的。在JDK8之前,接口中的成分包含:抽象方法和常量


2.3 接口成分的特点

2.3.1.抽象方法

注意:接口中的抽象方法默认会自动加上public abstract修饰程序员无需自己手写!! 按照规范:以后接口中的抽象方法建议不要写上public abstract。因为没有必要啊,默认会加上。

2.3.2 常量

在接口中定义的成员变量默认会加上:public static final修饰。也就是说在接口中定义的成员变量实际上是一个常量。这里是使用public static final修饰后,变量值就不可被修改,并且是静态化的变量可以直接用接口名访问,所以也叫常量。常量必须要给初始值。常量命名规范建议字母全部大写,多个单词用下划线连接。

案例演示

public interface InterF {
    // 抽象方法!
    //    public abstract void run();
    void run();


    //    public abstract String getName();
    String getName();


    //    public abstract int add(int a , int b);
    int add(int a , int b);




    // 它的最终写法是:
    // public static final int AGE = 12 ;
    int AGE  = 12; //常量
    String SCHOOL_NAME = "xx一中";


}

2.4 基本的实现

2.4.1 实现接口的概述

类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements关键字。

2.4.2 实现接口的格式

/**接口的实现:
    在Java中接口是被实现的,实现接口的类称为实现类。
    实现类的格式:*/
[修饰符] class 类名 implements 接口1,接口2,接口3...{




}

question:从上面格式可以看出,接口是可以被多实现的。大家可以想一想为什么呢?


往下来看



2.4.3 类实现接口的要求和意义

  1. 必须重写实现的全部接口中所有抽象方法。
  2. 如果一个类实现了接口,但是没有重写完全部接口的全部抽象方法,这个类也必须定义成抽象类。
  3. 意义:接口体现的是一种规范,接口对实现类是一种强制性的约束,要么全部完成接口申明的功能,要么自己也定义成抽象类。这正是一种强制性的规范。

2.4.4 类与接口基本实现案例

假如我们定义一个运动员的接口(规范),代码如下:

/**
   接口:接口体现的是规范。
 * */
public interface SportMan {
    void run(); // 抽象方法,跑步。
    void law(); // 抽象方法,遵守法律。
    String compittion(String project);  // 抽象方法,比赛。
}


接下来定义一个乒乓球运动员类,实现接口,实现接口的实现类代码如下:

package com.itheima._03接口的实现;
/**
 * 接口的实现:
 *    在Java中接口是被实现的,实现接口的类称为实现类。
 *    实现类的格式:
 *      [修饰符] class 类名 implements 接口1,接口2,接口3...{
 *
 *
 *      }
 * */
public class PingPongMan  implements SportMan {
    @Override
    public void run() {
        System.out.println("乒乓球运动员稍微跑一下!!");
    }


    @Override
    public void law() {
        System.out.println("乒乓球运动员守法!");
    }


    @Override
    public String compittion(String project) {
        return "参加"+project+"得金牌!";
    }
}

测试代码

/** 法律规范:接口*/
public interface Law {
    void rule();
}


/** 这一个运动员的规范:接口*/
public interface SportMan {
    void run();
}

然后定义一个实现类:

/**
 * Java中接口是可以被多实现的:
 *    一个类可以实现多个接口: Law ,SportMan
 *
 * */
public class JumpMan implements Law ,SportMan {
    @Override
    public void rule() {
        System.out.println("尊长守法");
    }


    @Override
    public void run() {
        System.out.println("训练跑步!");
    }
}

从上面可以看出类与接口之间是可以多实现的,我们可以理解成实现多个规范,这是合理的。

2.5 接口与接口的多继承

Java中,接口与接口之间是可以多继承的:也就是一个接口可以同时继承多个接口。大家一定要注意:

类与接口是实现关系

接口与接口是继承关系

接口继承接口就是把其他接口的抽象方法与本接口进行了合并。

案例演示:

public interface Abc {
    void go();
    void test();
}


/** 法律规范:接口*/
public interface Law {
    void rule();
    void test();
}


 *
 *  总结:
 *     接口与类之间是多实现的。
 *     接口与接口之间是多继承的。
 * */
public interface SportMan extends Law , Abc {
    void run();
}

2.6 JDK 8之后的接口新增方法

从JDK 8开始之后,接口不再纯洁了,接口中不再只是抽象方法,接口还可以有默认方法(也就是实例方法),和静态方法了,还包含了私有实例方法和私有静态方法

2.6.1 含有默认方法和静态方法

默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写。

静态方法:使用 static 修饰,供接口直接调用。

代码如下:

public interface InterFaceName {
    public default void method() {
        // 执行语句
    }
    public static void method2() {
        // 执行语句    
    }
}

2.6.2 含有私有方法和私有静态方法

私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用。

代码如下:

public interface InterFaceName {
    private void method() {
        // 执行语句
    }
}

2.6.3 新增方法的使用

默认方法和静态方法以及私有方法和私有静态方法遵循面向对象的继承关系使用原则,实现类依然可以访问接口的非私有方法,对于接口中的非私有静态方法,可以直接通过接口名进行访问。

重写默认方法注意(了解):

  • 子接口重写默认方法时,default关键字可以保留。
  • 实现类重写默认方法时,default关键字不可以保留。

2.7 实现多个接口使用注意事项

2.7.1 多个接口同名静态方法

如果实现了多个接口,多个接口中存在同名的静态方法并不会冲突,原因是只能通过各自接口名访问静态方法。

public interface A {
  public static void test(){


  }
}


 interface B {
    public static void test(){


    }
}


class C implements  A , B{
    public static void main(String[] args) {
        People.test();
        B.test();
       // C.test(); // 编译出错
    }
}

2.7.2 优先级的问题

当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法。代码如下:

定义接口:

interface A {
    public default void methodA(){
        System.out.println("AAAAAAAAAAAA");
    }
}

定义父类:

class D {
    public void methodA(){
        System.out.println("DDDDDDDDDDDD");
    }
}

定义父类:

class D {
    public void methodA(){
        System.out.println("DDDDDDDDDDDD");
    }
}

定义子类:

class C extends D implements A {
    // 未重写methodA方法
}

定义测试类:

public class Test {
    public static void main(String[] args) {
        C c = new C();
        c.methodA(); 
    }
}
输出结果:
DDDDDDDDDDDD

由此看出,我们可以对接口总结以下:

  • 接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static final修饰。
  • 接口中的方法全是抽象方法,默认会自动加上public abstract修饰
  • JDK 8开始,接口不再纯洁,支持静态方法,默认方法,私有方法。
  • 接口中,没有构造器,不能创建对象
  • 类与接口是多实现的
  • 接口与接口是多继承的
  • 接口体现的规范。



《代码块》

代码块是类的五大成分之一(成员变量,构造器,方法,代码块,内部类)
代码块按照有无static修饰可以分为静态代码块和实例代码块。
静态代码块:
    -- 有static修饰,属于当前类本身,与类一起优先加载,加载的时候会自动触发执行。
    -- 格式:
        static{
        }
    -- 静态代码块的作用:可以在类执行方法之前进行静态资源数据的初始化操作。





上代码:

public class CodeDemo01 {
    public static List<String> datas = new ArrayList<>();
    // 静态代码块。
    static {
        // 静态代码块的作用:可以在类执行方法之前进行静态资源数据的初始化操作。
        System.out.println("静态代码块被触发执行~~~~~~~~");
        datas.add("东");
        datas.add("南");
        datas.add("西");
        datas.add("北");
    }


    public static void main(String[] args) {
        System.out.println(datas);
    }
tips:实例代码块:
   -- 无static修饰的的代码块,属于类的每个对象的,会与对象一起加载,
        每次创建对象的时候都会自动执行一次实例代码块的执行。
   -- 格式:{}
   -- 可以用于初始化实例资源的数据。
   -- 实例代码块的代码相当于是提取到每个构造器中去执行的。



final关键字


3.1 概述

学习了继承后,我们知道,子类可以在父类的基础上改写父类内容,比如,方法重写。那么我们能不能随意的继承API中提供的类,改写其内容呢?显然这是不合适的。为了避免这种随意改写的情况,Java提供了final 关键字,用于修饰不可改变内容。

  • final: 不可改变,最终的含义。可以用于修饰类、方法和变量。
    • 类:被修饰的类,不能被继承。
    • 方法:被修饰的方法,不能被重写。
    • 变量:被修饰的变量,有且仅能被赋值一次。

3.2 使用方式

3.2.1 修饰类

final修饰的类,不能被继承。

格式如下:

final class 类名 {
}

代码:

final class Fu {
}
// class Zi extends Fu {} // 报错,不能继承final的类

查询API发现像 public final class Stringpublic final class Mathpublic final class Scanner 等,很多我们学习过的类,都是被final修饰的,目的就是供我们使用,而不让我们所以改变其内容。

3.2.2 修饰方法

final修饰的方法,不能被重写。格式如下:

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

代码:

class Fu2 {
  final public void show1() {
    System.out.println("Fu2 show1");
  }
  public void show2() {
    System.out.println("Fu2 show2");
  }
}


class Zi2 extends Fu2 {
//  @Override
//  public void show1() {
//    System.out.println("Zi2 show1");
//  }
  @Override
  public void show2() {
    System.out.println("Zi2 show2");
  }
}

3.2.3 修饰变量-局部变量

  1. 局部变量——基本类型基本类型的局部变量,被final修饰后,只能赋值一次,不能再更改。代码如下:
public class FinalDemo1 {
    public static void main(String[] args) {
        // 声明变量,使用final修饰
        final int a;
        // 第一次赋值 
        a = 10;
        // 第二次赋值
        a = 20; // 报错,不可重新赋值


        // 声明变量,直接赋值,使用final修饰
        final int b = 10;
        // 第二次赋值
        b = 20; // 报错,不可重新赋值
    }
}

想一下,如下两种写法,哪种可以通过编译?

写法1:

final int c = 0;
for (int i = 0; i < 10; i++) {
    c = i;
    System.out.println(c);
}

写法2:

for (int i = 0; i < 10; i++) {
    final int c = i;
    System.out.println(c);
}

根据 final 的定义,不难看出,写法1报错!写法2,为什么通过编译呢?因为每次循环,都是一次新的变量c。这也是大家需要注意的地方。

3.2.4 修饰变量-实例成员变量

成员变量涉及到初始化的问题,初始化方式有显示初始化和构造器初始化,只能选择其中一个:

  • 显示初始化(在定义成员变量的时候立马赋值);
public class Student {
    final int num = 10;
}


构造器初始化(在构造器中赋值一次)。

注意:每个构造器中都要赋值一次!

public class Student {
    final int num = 10;
    final int num2;


    public Student() {
        this.num2 = 20;
//     this.num2 = 20;
    }
    
     public Student(String name) {
        this.num2 = 20;
//     this.num2 = 20;
    }
}

tips:被final修饰的常量名称,一般都有书写规范,所有字母都大写。


单例设计模式



我们正常情况下一个类可以创建多个对象

public static void main(String[] args) {
  // 正常情况下一个类可以创建多个对象
  Person p1 = new Person();
  Person p2 = new Person();
  Person p3 = new Person();
}


4.1 单例设计模式的作用

单例模式,是一种常用的软件设计模式。通过单例模式可以保证系统中,应用该模式的这个类只有一个实例。即一个类只有一个对象实例。

4.2 单例设计模式实现步骤

  1. 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
  2. 在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型的成员变量。
  3. 定义一个静态方法返回这个唯一对象。

4.3 单例设计模式的类型

根据实例化对象的时机单例设计模式又分为以下两种:

  1. 饿汉单例设计模式
  2. 懒汉单例设计模式

4.4 饿汉单例设计模式

饿汉单例设计模式就是使用类的时候已经将对象创建完毕,不管以后会不会使用到该实例化对象,先创建了再说。很着急的样子,故被称为“饿汉模式”。

代码如下:

public class Singleton {
    // 1.将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
    private Singleton() {}


    // 2.在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型的成员变量。
    private static final Singleton instance = new Singleton();
    
    // 3.定义一个静态方法返回这个唯一对象。
    public static Singleton getInstance() {
        return instance;
    }
}

4.5 懒汉单例设计模式

懒汉单例设计模式就是调用getInstance()方法时实例才被创建,先不急着实例化出对象,等要用的时候才例化出对象。不着急,故称为“懒汉模式”。

代码如下:

public class Singleton {


    // 2.在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型的成员变量。
    private static Singleton instance;
    
    // 1.将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
    private Singleton() {}
    
    // 3.定义一个静态方法返回这个唯一对象。要用的时候才例化出对象
    public static Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

注意:懒汉单例设计模式在多线程环境下可能会实例化出多个对象,不能保证单例的状态。我们在学习完多线程的时候还会再讲解如何解决这个问题。

summary:

单例模式可以保证系统中一个类只有一个对象实例。

实现单例模式的步骤:

  1. 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
  2. 在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型的成员变量。
  3. 定义一个静态方法返回这个唯一对象。

枚举

question:为什么会有枚举


下面我们不使用枚举

假设我们要定义一个人类,人类中包含姓名和性别。通常会将性别定义成字符串类型,效果如下:

public class Person {
    private String name;
    private String sex;


    public Person() {
    }


    public Person(String name, String sex) {
        this.name = name;
        this.sex = sex;
    }
  
    // 省略get/set/toString方法
}
public class Demo01 {
    public static void main(String[] args) {
        Person p1 = new Person("张三", "男");
        Person p2 = new Person("张三", "abc"); // 因为性别是字符串,所以我们可以传入任意字符串
    }
}

所以从此看出:不使用枚举存在的问题:可以给性别传入任意的字符串,导致性别是非法的数据,不安全。

5.2 枚举的作用与应用场景

枚举的作用:一个方法接收的参数是固定范围之内的时候,那么即可使用枚举。

5.3 枚举的基本语法

5.3.1 枚举的概念

枚举是一种特殊类。枚举是有固定实例个数的类型,我们可以把枚举理解成有固定个数实例的多例模式。

5.3.2 定义枚举的格式

enum 枚举名 {
    第一行都是罗列枚举实例,这些枚举实例直接写大写名字即可。
}

5.3.3 案例

  1. 定义枚举:BOY表示男,GIRL表示女
enum Sex {
    BOY, GIRL; // 男,女
}

2.Perosn中的性别有String类型改为Sex枚举类型

public class Person {
    private String name;
    private Sex sex;


    public Person() {
    }


    public Person(String name, Sex sex) {
        this.name = name;
        this.sex = sex;
    }
    // 省略get/set/toString方法
}

3.使用是只能传入枚举中的固定值

public class Demo02 {
    public static void main(String[] args) {
        Person p1 = new Person("张三", Sex.BOY);
        Person p2 = new Person("张三", Sex.GIRL);
        Person p3 = new Person("张三", "abc");
    }
}


5.3.4 枚举的其他内容

枚举的本质是一个类,我们刚才定义的Sex枚举最终效果如下:

enum Sex {
    BOY, GIRL; // 男,女
}


// 枚举的本质是一个类,我们刚才定义的Sex枚举相当于下面的类
final class SEX extends java.lang.Enum<SEX> {
    public static final SEX BOY = new SEX();
    public static final SEX GIRL = new SEX();
    public static SEX[] values();
    public static SEX valueOf(java.lang.String);
    static {};
}

枚举的本质是一个类,所以枚举中还可以有成员变量,成员方法等

public enum Sex {
    BOY(18), GIRL(16);


    public int age;


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


    public void showAge() {
        System.out.println("年龄是: " + age);
    }
}
public class Demo03 {
    public static void main(String[] args) {
        Person p1 = new Person("张三", Sex.BOY);
        Person p2 = new Person("张三", Sex.GIRL);


        Sex.BOY.showAge();
        Sex.GIRL.showAge();
    }
}

summary:

枚举的作用:枚举通常可以用于做信息的分类,如性别,方向,季度等。

  • 枚举类在第一行罗列若干个枚举对象。(多例)
  • 第一行都是常量,存储的是枚举类的对象。
  • 枚举是不能在外部创建对象的,枚举的构造器默认是私有的。
  • 枚举通常用于做信息的标志和分类。
  • 枚举的特点:
  • 1.枚举类不能被继承。
  • 2.枚举默认继承了枚举类型:java.lang.Enum*
  • 3.枚举类的第一行都是罗列枚举类的对象。他们都是常量
  • 4.枚举类的构造器是私有的,枚举类相当于是多例模式。
  • 枚举用于做信息的分类和标志。
  • 枚举类的第一行都是罗列枚举类的对象,枚举类相当于是多例模式。


举报
评论 0