类、枚举与接口

接口,枚举,抽象类(都是由class变过来的)
enum反编译过来就是class或abstract class

定义接口的原因:
当初些抽象类的时候(假设抽象类中一个普通的属性都没有,全是由
public static final修饰的 所有的方法都是抽象方法,都由public abstract修饰)
人们不愿意写这么多关键字,所以定义了一个新的关键字interface,所有关键字省略
特殊的抽象类就变成接口

enum可以拿抽象类来写(枚举是某种类型的取值是若干有限集合中的一个)
其中转变的过程为:
限制class Gender{}的取值(实例对象)只有一个所以写成

class Gender{
    private Gender(){}
    private static Gender g = new Gender();
    static public void getInstance(){
        return g;
    }
}

但不够方便,所以改为

class Gender{
    private Gender(){}
    public static Gender g = new Gender();

}

但因为是类变量,而且值还可以改,值被所有人共享,万一改成null,
就再也获取不到Gender的实例了,所以改为

class Gender{
    private Gender(){}
    public final static Gender g = new Gender();

}

此时Gender的取值只能为g(共享的常量)当有多个时:

class Gender{
    private Gender(){}
    public final static Gender FEMALE1 = new Gender();
    public final static Gender MALE1 = new Gender();
    public final static Gender FEMALE2 = new Gender();
    public final static Gender MALE2 = new Gender();

}

此时唯一不同的就是4个变量(且都用类名来调用)为了简化
所以在你构造器没有参数的时候就可以写成

enum Gender{
    FEMALE1,MALE1,FEMALE2,MALE2
}

所以刚才的类就替换成了枚举
枚举里可以加抽象方法(如果一个类里有抽象方法,那么这个类就是抽象的)

abstract class Gender{
    private Gender(){}
    abstract void test();
    public final static Gender FEMALE1 = new Gender();
    public final static Gender MALE1 = new Gender();
    public final static Gender FEMALE2 = new Gender();
    public final static Gender MALE2 = new Gender();

}

此时abstract class 是不能被实例化的
只能使用匿名内部类来生成对象

abstract class Gender{
    private Gender(){}
    abstract void test();
    public final static Gender FEMALE1 = new Gender(){
        public void test(){}
    };
    public final static Gender MALE1 = new Gender(){
        public void test(){}
    };
    public final static Gender FEMALE2 = new Gender(){
        public void test(){}
    };
    public final static Gender MALE2 = new Gender(){
        public void test(){}
    };
}

而枚举要实现接口要做的操作

enum Gender{
    FEMALE(){
        public void test(){}
    },MALE(){
        public void test(){}
    };
    abstract void test();
}

所以说MALE和FEMALE都是enum的一个实例
用javap -v反编译以下代码:

enum Gender{
    FEMALE(){
        public void test(){}
    },MALE(){
        public void test(){}
    };
    abstract void test();
}

得到的结果为:

Classfile /home/briup/Gender.class
  Last modified 2017-8-24; size 937 bytes
  MD5 checksum 5ada6ef037132305206b15964108ae09
  Compiled from "Test.java"
abstract class Gender extends java.lang.Enum<Gender>
  Signature: #37                          // Ljava/lang/Enum<LGender;>;
  SourceFile: "Test.java"
  InnerClasses:
       static #12; //class Gender$2
       static #8; //class Gender$1
  minor version: 0
  major version: 51
  flags: ACC_SUPER, ACC_ABSTRACT, ACC_ENUM
Constant pool:
   #1 = Methodref          #5.#40         //  Gender."<init>":(Ljava/lang/String;I)V
   #2 = Fieldref           #5.#41         //  Gender.$VALUES:[LGender;
   #3 = Methodref          #42.#43        //  "[LGender;".clone:()Ljava/lang/Object;
   #4 = Class              #23            //  "[LGender;"
   #5 = Class              #44            //  Gender
   #6 = Methodref          #16.#45        //  java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
   #7 = Methodref          #16.#46        //  java/lang/Enum."<init>":(Ljava/lang/String;I)V
   #8 = Class              #47            //  Gender$1
   #9 = String             #19            //  FEMALE
  #10 = Methodref          #8.#40         //  Gender$1."<init>":(Ljava/lang/String;I)V
  #11 = Fieldref           #5.#48         //  Gender.FEMALE:LGender;
  #12 = Class              #49            //  Gender$2
  #13 = String             #21            //  MALE
  #14 = Methodref          #12.#40        //  Gender$2."<init>":(Ljava/lang/String;I)V
  #15 = Fieldref           #5.#50         //  Gender.MALE:LGender;
  #16 = Class              #51            //  java/lang/Enum
  #17 = Utf8
  #18 = Utf8               InnerClasses
  #19 = Utf8               FEMALE
  #20 = Utf8               LGender;
  #21 = Utf8               MALE
  #22 = Utf8               $VALUES
  #23 = Utf8               [LGender;
  #24 = Utf8               values
  #25 = Utf8               ()[LGender;
  #26 = Utf8               Code
  #27 = Utf8               LineNumberTable
  #28 = Utf8               valueOf
  #29 = Utf8               (Ljava/lang/String;)LGender;
  #30 = Utf8               <init>
  #31 = Utf8               (Ljava/lang/String;I)V
  #32 = Utf8               Signature
  #33 = Utf8               ()V
  #34 = Utf8               test
  #35 = Utf8               (Ljava/lang/String;ILGender$1;)V
  #36 = Utf8               <clinit>
  #37 = Utf8               Ljava/lang/Enum<LGender;>;
  #38 = Utf8               SourceFile
  #39 = Utf8               Test.java
  #40 = NameAndType        #30:#31        //  "<init>":(Ljava/lang/String;I)V
  #41 = NameAndType        #22:#23        //  $VALUES:[LGender;
  #42 = Class              #23            //  "[LGender;"
  #43 = NameAndType        #52:#53        //  clone:()Ljava/lang/Object;
  #44 = Utf8               Gender
  #45 = NameAndType        #28:#54        //  valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
  #46 = NameAndType        #30:#31        //  "<init>":(Ljava/lang/String;I)V
  #47 = Utf8               Gender$1
  #48 = NameAndType        #19:#20        //  FEMALE:LGender;
  #49 = Utf8               Gender$2
  #50 = NameAndType        #21:#20        //  MALE:LGender;
  #51 = Utf8               java/lang/Enum
  #52 = Utf8               clone
  #53 = Utf8               ()Ljava/lang/Object;
  #54 = Utf8               (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
{
  public static final Gender FEMALE;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM

  public static final Gender MALE;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM

  public static Gender[] values();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: getstatic     #2                  // Field $VALUES:[LGender;
         3: invokevirtual #3                  // Method "[LGender;".clone:()Ljava/lang/Object;
         6: checkcast     #4                  // class "[LGender;"
         9: areturn
      LineNumberTable:
        line 1: 0

  public static Gender valueOf(java.lang.String);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: ldc_w         #5                  // class Gender
         3: aload_0
         4: invokestatic  #6                  // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
         7: checkcast     #5                  // class Gender
        10: areturn
      LineNumberTable:
        line 1: 0
 public abstract void test();
    flags: ACC_PUBLIC, ACC_ABSTRACT

  Gender(java.lang.String, int, Gender$1);
    flags: ACC_SYNTHETIC
    Code:
      stack=3, locals=4, args_size=4
         0: aload_0
         1: aload_1
         2: iload_2
         3: invokespecial #1                  // Method "<init>":(Ljava/lang/String;I)V
         6: return
      LineNumberTable:
        line 1: 0

  static {};
    flags: ACC_STATIC
    Code:
      stack=4, locals=0, args_size=0
         0: new           #8                  // class Gender$1
         3: dup
         4: ldc           #9                  // String FEMALE
         6: iconst_0
         7: invokespecial #10                 // Method Gender$1."<init>":(Ljava/lang/String;I)V
        10: putstatic     #11                 // Field FEMALE:LGender;
        13: new           #12                 // class Gender$2
        16: dup
        17: ldc           #13                 // String MALE
        19: iconst_1
        20: invokespecial #14                 // Method Gender$2."<init>":(Ljava/lang/String;I)V
        23: putstatic     #15                 // Field MALE:LGender;
        26: iconst_2
        27: anewarray     #5                  // class Gender
        30: dup
        31: iconst_0
        32: getstatic     #11                 // Field FEMALE:LGender;
        35: aastore
        36: dup
        37: iconst_1
        38: getstatic     #15                 // Field MALE:LGender;
        41: aastore
        42: putstatic     #2                  // Field $VALUES:[LGender;
        45: return
      LineNumberTable:
        line 2: 0
        line 5: 13
        line 1: 26
}

由此可见,java中的接口和枚举都是人们为了简化操作而专门设计的!(其实都是类o(* ̄︶ ̄*)o)

时间: 2024-10-08 03:30:12

类、枚举与接口的相关文章

C#枚举器接口IEnumerator的实现

原文(http://blog.csdn.net/phpxin123/article/details/7897226) 在C#中,如果一个类要使用foreach结构来实现迭代,就必须实现IEnumerable或IEnumerator接口.其中,IEnumerator接口定义了实现枚举器模式的方法IEnumerator.MoveNext()和IEnumerator.Reset()和成员属性IEnumerator.Count,而IEnumerable接口的唯一方法IEnumerable.GetEnum

C#中的类属性和接口属性

类属性 类属性是类成员函数的另一种形式,它的主要任务是实现对数据的间接访问,属性的get块和set块的定义中必须明确指出是对什么数据进行访问.对于自动属性,编译器会自动创建对应的数据字段,并且实现属性的get块和set块. 接口属性 接口中可以定义属性,接口属性可以只拥有get块或set块,如果只指定了set或get访问,那么该接口属性表明,对于外部,它只允许这一种访问,这会对类实现接口属性时产生一种约束,即类中具体定义该接口属性时,其访问权限不能大于接口中指定的权限,虽然类中可以为该接口属性补

Java基础-接口.编写2个接口:InterfaceA和InterfaceB;在接口InterfaceA中有个方法void printCapitalLetter();在接口InterfaceB中有个方法void printLowercaseLetter();然 后写一个类Print实现接口InterfaceA和InterfaceB,要求 方法 实现输出大写英文字母表的功能,printLowerca

#34.编写2个接口:InterfaceA和InterfaceB:在接口InterfaceA中有个方法void printCapitalLetter():在接口InterfaceB中有个方法void printLowercaseLetter():然 后写一个类Print实现接口InterfaceA和InterfaceB,要求      方法 实现输出大写英文字母表的功能,printLowercaseLetter()方法实现输出小写英文 字母表的功能.再写一个主类E,在主类E的main方法中创建P

探Java多线程Thread类和Runnable接口之间的联系

首先复习一下Java多线程实现机制,Java实现多线程方法有如下这么几种: 1.继承了(extends)Thread类 2.实现了(implements)Runnable接口 也就是说  有如下两种情况 情况1: 继承Thread类.重写其方法run() .    然后new之.调用Start()方法 1 public class TestThread 2 { 3 private int i; 4 public static void main(String[] args) 5 { 6 // T

关于多个类实现同一个接口的相关资料

http://liusu.iteye.com/blog/136690 某一天,某一个需求修改完成之后,提交代码.我修改了一个接口,在接口文件中添加了一个方法,并且在实现类中实现.但运维同事编译时告诉我出错了,为什么呢,因为不知道谁在代码路径中把这个接口的实现类做了一个备份,我没有在备份文件中实现添加的方法,从而报错.在这个问题上,突然发现自己只是了解一个接口多个实现类,但是从来没有深入了解过,顾借此机会整理一些东西吧.欢迎补充 1.一个接口,多个类implements该接口 public cla

类Collections与接口Comparator

类Collections与接口Comparator的简单使用 1 import java.util.ArrayList; 2 import java.util.Collections; 3 import java.util.Comparator; 4 import java.util.List; 5 6 public class TestCompare { 7 8 public static void main(String[] args) { 9 10 List<BookInfo> list

Java 多线程——Thread类和Runable接口

在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限, 下面看例子: [java] view plaincopy package org.thread.demo; class MyThread extends Thread{ private String name; public

java基础知识回顾之javaIO类--File类应用:过滤器接口FilenameFilter和FileFilter

FilenameFilter和FileFilter都是用来过滤文件,例如过滤,以.jpg或者.java结尾的文件,通过看他们的源码:通过使用File类中String[] list(FilenameFilter filter)或者public File[] listFiles(FileFilter filter)方法,把FilenameFilter或者FileFilter接口对象作为参数传入,通过实现接口里面的 boolean accept(File dir, String name) 或者boo

Mybatis自动生成实体类、dao接口和mapping映射文件

由于Mybatis是一种半自动的ORM框架,它的工作主要是配置mapping映射文件,为了减少手动书写映射文件,可以利用mybatis生成器,自动生成实体类.dao接口以及它的映射文件,然后直接拷贝到工程中稍微修改就可以直接使用了. 生成器目录如下: 首先进入lib文件夹中,该目录如下: (图上文件下载地址:http://download.csdn.net/detail/qiwei31229/9790909) 主要修改generatorConfig.xml <?xml version="1

Apache—DBUtils框架简介、DbUtils类、QueryRunner类 、ResultSetHandler接口

Apache—DBUtils框架简介.DbUtils类.QueryRunner类 .ResultSetHandler接口 commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能.因此dbutils成为很多不喜欢hibernate的公司的首选. API介绍: org.apache.commons.dbutils.QueryRunner --BDMa