面向对象/内部类/枚举类/包装类

内部类(inner)
  1. 内部类定义
    将一个类A定义在另一个类B里面,里面的那个类A就称为内部类(InnerClass),类B则称为外部类(OuterClass)
  2. 为什么需要内部类?
    具体来说,当一个事物A的内部,还有一个部分需要一个完整的结构B进行描述,而这个内部的完整的结构B又只为外部事物A提供服务,不在其他地方单独使用,那么整个内部的完整结构B最好使用内部类。

总的来说,高内聚、低耦合的面向对象开发原则。

  1. 举例
    Thread类内部声明了State类,表示线程的生命周期
    HashMap类中声明了Node类,表示封装的key和value

  2. 内部类的分类:(参考变量的分类)

    成员内部类:直接声明在外部类的里面。
    使用static修饰的:静态的成员内部类
    不使用static修饰的:非静态的成员内部类

    **局部内部类:**声明在方法内、构造器内、代码块内的内部类
    匿名的局部内部类
    非匿名的局部内部类

  3. 内部类知识:

成员内部类的理解
如何创建成员内部类的实例
如何在成员内部类中调用外部类的结构
局部内部类的基本使用

  1. 关于成员内部类的理解:

    从类的角度看:

    • 可以声明属性、方法、构造器、代码块、内部类等结构
    • 可以声明父类,
    • 可以实现接口
    • 可以使用final修饰
    • 可以使用abstract修饰

    从外部类的成员的角度看:

    • 在内部可以调用外部类的结构。比如:属性、方法等
    • 可以使用public、缺省权限修饰之外
    • 可以使用private、protected修饰
    • 可以使用static修饰

举例:

public class OuterClassTest1 {
    //说明:局部内部类的使用
    public void method1(){
        //局部内部类
        class A{
           //可以声明属性、方法等
        }
    }
    //开发中的场景
    public Comparable getInstance(){
        //提供了实现了Comparable接口的类
        //方式1:提供了接口的实现类的对象
        class MyComparable implements Comparable{
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        }
        MyComparable m = new MyComparable();
        return m;
        //方式2:提供了接口的实现类的匿名对象
        class MyComparable implements Comparable{
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        }
        return new MyComparable();
        //方式3:提供了接口的匿名实现类的对象
        Comparable c = new Comparable(){
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
        return c;
        //方式4:提供了接口的匿名实现类的匿名对象
        return new Comparable(){
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
    }
}
  1. 关于局部内部类的说明:
枚举类(enum)
  1. 枚举类的理解:
    枚举类型本质上也是一种类,只不过是这个类的对象是有限的、固定的几个,不能让用户随意创建。
  2. 举例:
  • 星期:Monday(星期一)…Sunday(星期天)
  • 性别:Man(男)、Woman(女)
  • 月份:January(1月)…December(12月)
  • 季节:Spring(春节)…Winter(冬天)
  • 三原色:red(红色)、green(绿色)、blue(蓝色)
  • 支付方式:Cash(现金)、WeChatPay(微信)、Alipay(支付宝)、BankCard(银行卡)、CreditCard(信用卡)
  • 就职状态:Busy(忙碌)、Free(空闲)、Vocation(休假)、Dimission(离职)
  • 订单状态:Nonpayment(未付款)、Paid(已付款)、Fulfilled(已配货)、Delivered(已发货)、Checked(已确认收货)、Return(退货)、Exchange(换货)、Cancel(取消)
  • 线程状态:创建、就绪、运行、阻塞、死亡
  1. 开发中的建议:

开发中,如果针对于某个类,其实例是确定个数的。则推荐将此类声明为枚举类
如果枚举类的实例只有一个,则可以看做是单例的实现方式。

  1. 自定义枚举类
  public class SeasonTest {
      public static void main(String[] args) {
  //        Season.SPRING = null;
  
          System.out.println(Season.SPRING);
  
          System.out.println(Season.SUMMER.getSeasonName());
          System.out.println(Season.SUMMER.getSeasonDesc());
      }
  }
  
  //jdk5.0之前定义枚举类的方式
  class Season{
      //2. 声明当前类的对象的实例变量,使用private final修饰
      private final String seasonName;//季节的名称
      private final String seasonDesc;//季节的描述
  
      //1. 私有化类的构造器
      private Season(String seasonName,String seasonDesc){
          this.seasonName = seasonName;
          this.seasonDesc = seasonDesc;
      }
  
      //3. 提供实例变量的get方法
      public String getSeasonName() {
          return seasonName;
      }
  
      public String getSeasonDesc() {
          return seasonDesc;
      }
      //4. 创建当前类的实例,需要使用public static final修饰
      public static final Season SPRING = new Season("春天","春暖花开");
      public static final Season SUMMER = new Season("夏天","夏日炎炎");
      public static final Season AUTUMN = new Season("秋天","秋高气爽");
      public static final Season WINTER = new Season("冬天","白雪皑皑");
  
      @Override
      public String toString() {
          return "Season{" +
                  "seasonName='" + seasonName + '\'' +
                  ", seasonDesc='" + seasonDesc + '\'' +
                  '}';
      }
  }
  1. 使用enum定义枚举类
  
  举例1
  enum Season1 implements Info{
      //1. 必须在枚举类的开头声明多个对象。对象之间使用,隔开
      SPRING("春天","春暖花开"),
      SUMMER("夏天","夏日炎炎"),
      AUTUMN("秋天","秋高气爽"),
      WINTER("冬天","白雪皑皑");
  
      //2. 声明当前类的对象的实例变量,使用private final修饰
      private final String seasonName;//季节的名称
      private final String seasonDesc;//季节的描述
  
      //3. 私有化类的构造器
      private Season1(String seasonName,String seasonDesc){
          this.seasonName = seasonName;
          this.seasonDesc = seasonDesc;
      }
  
      //4. 提供实例变量的get方法
      public String getSeasonName() {
          return seasonName;
      }
  
      public String getSeasonDesc() {
          return seasonDesc;
      }
  
      @Override
      public String toString() {
          return "Season1{" +
                  "seasonName='" + seasonName + '\'' +
                  ", seasonDesc='" + seasonDesc + '\'' +
                  '}';
      }
  
      @Override
      public void show() {
          System.out.println("这是一个季节");
      }
  }
  举例2
  public class EmployeeTest {
      public static void main(String[] args) {
  
          Employee e1 = new Employee("Tom",21,Status.BUSY);
          System.out.println(e1);
  
      }
  
      /**
       * 定义公司中员工的状态
       *
       * @author shkstart
       * @create 11:18
       */
      public enum Status {
  
          BUSY,FREE,VOCATION,DIMISSION;
  
      }
      
      
      public static class Employee {
      
          private String name;
          private int age;
          private Status status;
      
          public Employee() {
          }
      
          public Employee(String name, int age, Status status) {
              this.name = name;
              this.age = age;
              this.status = status;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getAge() {
              return age;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
          public Status getStatus() {
              return status;
          }
      
          public void setStatus(Status status) {
              this.status = status;
          }
      
          @Override
          public String toString() {
              return "Employee{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      ", status=" + status +
                      '}';
          }
      }
  
  
     
  }
  1. Enum中的常用方法:
    6.1 使用enum关键字定义的枚举类,默认其父类是java.lang.Enum类不要再显示的定义其父类。否则报错。
    6.2 熟悉Enum类中常用的方法
    String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法!
    (关注)static 枚举类型[] values():返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值,是一个静态方法
    (关注)static 枚举类型 valueOf(String name):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常:IllegalArgumentException。
    String name():得到当前枚举常量的名称。建议优先使用toString()。
    int ordinal():返回当前枚举常量的次序号,默认从0开始
public class SeasonTest1 {
    public static void main(String[] args) {
//        System.out.println(Season1.SPRING.getClass());
//        System.out.println(Season1.SPRING.getClass().getSuperclass());
//        System.out.println(Season1.SPRING.getClass().getSuperclass().getSuperclass());

        //测试方法
        //1. toString()
        System.out.println(Season1.SPRING);
        System.out.println(Season1.AUTUMN);

        //2. name()
        System.out.println(Season1.SPRING.name());

        //3. vlaues()
        Season1[] values = Season1.values();
        for (int i = 0; i < values.length; i++) {
            System.out.println(values[i]);
        }

        //4. valueOf(String objName):返回当前枚举类中名称为objName的枚举类对象。
        //如果枚举类中不存在objName名称的对象,则报错。
        String objName = "WINTER";
//        objName = "WINTER1";
        Season1 season1 = Season1.valueOf(objName);
        System.out.println(season1);

        //5.ordinal()
        System.out.println(Season1.AUTUMN.ordinal());

        //通过枚举类的对象调用重写接口中的方法
        Season1.SUMMER.show();
    }
}
  1. 枚举类实现接口的操作
    情况1:枚举类实现接口,在枚举类中重写接口中的抽象方法。当通过不同的枚举类对象调用此方法时,执行的是同一个方法。

    System.out.println("Season2.SUMMER.show()");
    
    interface Info1{
        void show();
    }
    enum Season2 implements Info1{
        SPRING("春天","春暖花开"),
        SUMMER("夏天","夏日炎炎")AUTUMN("秋天","秋高气爽")WINTER("冬天","白雪皑皑");
        public void show(){
            return "这是一个季节";
        }   
    }
    

    情况2:让枚举类的每一个对象重写接口中的抽象方法。当通过不同的枚举类对象调用此方法时,执行的是不同的实现的方法。

interface Info1{
    void show();
}

//jdk5.0中使用enum关键字定义枚举类
enum Season2 implements Info1{
    //1. 必须在枚举类的开头声明多个对象。对象之间使用,隔开
    SPRING("春天","春暖花开"){
        public void show(){
            System.out.println("春天在哪里?");
        }
    },
    SUMMER("夏天","夏日炎炎"){
        public void show(){
            System.out.println("宁静的夏天");
        }
    },
    AUTUMN("秋天","秋高气爽"){
        public void show(){
            System.out.println("秋意浓");
        }
    },
    WINTER("冬天","白雪皑皑"){
        public void show(){
            System.out.println("大约在冬季");
        }
    };
注释了解(annotation)
  1. Annotation的理解

当前阶段 , 相当于保护机制 , 会帮你校验对应的 ,

  1. 注解的应用场景:
    示例1:生成文档相关的注解
    示例2:在编译时进行格式检查(JDK内置的三个基本注解)
    示例3:跟踪代码依赖性,实现替代配置文件功能

  2. Java基础涉及到的三个常用注解
    @Override: 限定重写父类方法,该注解只能用于方法
    @Deprecated: 用于表示所修饰的元素(类,方法等)已过时。通常是因为所修饰的结构危险存在更好的选择
    @SuppressWarnings: 抑制编译器警告 , 没使用

  3. 元注解的理解:
    元注解:对现有的注解进行解释说明的注解。

讲4个元注解:
(1)@Target:用于描述注解的使用范围
可以通过枚举类型ElementType的10个常量对象来指定
TYPE,METHOD,CONSTRUCTOR,PACKAGE…

(2)@Retention:用于描述注解的生命周期
可以通过枚举类型RetentionPolicy的3个常量对象来指定
SOURCE(源代码)、CLASS(字节码)、RUNTIME(运行时)
唯有RUNTIME阶段才能被反射读取到。

(3)@Documented:表明这个注解应该被 javadoc工具记录。
(4)@Inherited:允许子类继承父类中的注解

拓展: 元数据。
String name = “Tom”;

框架 = 注解 + 反射 + 设计模式 (一般在自定义框架中出现)

包装类
  1. 为什么要使用包装类?
    为了使得基本数据类型的变量具备引用数据类型变量的相关特征(比如:封装性、继承性、多态性),我们给各个基本数据
    类型的变量都提供了对应的包装类。

  2. (掌握)基本数据类型对应的包装类类型
    byte -> Byte
    short -> Short
    int -> Integer
    long -> Long
    float -> Float
    double ->Double

char -> Character
boolean -> Boolean

  1. 掌握基本数据类型 与 包装类之间的转换。
    3.1 为什么需要转换

    一方面,在有些场景下,需要使用基本数据类型对应的包装类的对象。此时就需要将基本数据类型的变量转换为
    包装类的对象。比如:ArrayList的add(Object obj);Object类的equals(Object obj)
    对于包装类来讲,既然我们使用的是对象,那么对象是不能进行+ - * /等运算的。为了能够进行这些运算,就
    需要将包装类的对象转换为基本数据类型的变量。

    3.2 如何转换:
    (装箱)基本数据类型 —> 包装类:① 使用包装类的构造器 ② (建议)调用包装类的valueOf(xxx xx)
    (拆箱)包装类 —> 基本数据类型:调用包装类的xxxValue()

    注意:原来使用基本数据类型变量的位置,改成包装类以后,对于成员变量来说,其默认值变化了!

    jdk5.0新特性:自动装箱、自动拆箱。

  2. String 与 基本数据类型、包装类之间的转换。

    基本数据类型、包装类 —> String类型:① 调用String的重载的静态方法valueOf(xxx xx) ; ② 基本数据类型的变量 + “”

    String类型 —> 基本数据类型、包装类: 调用包装类的静态方法:parseXxx()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值