• 类、枚举与接口


    接口,枚举,抽象类(都是由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)

  • 相关阅读:
    .cu文件属性中没有“CUDA C/C++”的原因
    QT QGraphicsView 在鼠标点击处进行放大缩小
    VS2017+Qt使用QChartsView过程中遇到的问题
    QString与char*的相互转换
    QT -- 对话框获取文件夹下所选图像名称
    Qt -- 获取文件夹中的文件/文件夹名字
    C/C++取数据中高8位,低8位,合成新数据
    C/C++中的位运算
    求解逆矩阵的常用三种方法
    Javascript定义类(class)的三种方法
  • 原文地址:https://www.cnblogs.com/wsyblog/p/7435557.html
Copyright © 2020-2023  润新知