内部类和枚举的学习使用笔记

重要内容

  1. 匿名内部类的使用方式(明确什么时候可以用,匿名内部类的底层原理)

  2. 枚举的定义方式与基本使用


内部类

内部类:是类中的五大成分之一(成员变量、方法、构造器、内部类、代码块),如果一个类定义在另一个类的内部,这个类就是内部类。

内部类、成员内部类(了解)

内部类的概述:

当一个类的内部定义了一个类,那么里面的这个类就是内部类!

成员内部类:

就是在类的内部定义了一个新的类,就是类中的一个普通成员。

public class Outer {
    //成员内部类
    public class Inner{
        //代码块
    }
}

创建对象的格式:

//外部类名.内部类名 对象名 = new 外部类(...). new 内部类(...);

Outer.Inner in = new new Outer().new Inner();

成员内部类的使用方式:

public class Person {
    private String name;
    private int age;

    //每个人都有心脏Heart(心脏本质上是一个完整的事物,但是心脏在人体的内部) 可以声明为人类的内部类(普通成员内部类)
    public class Heart {
        //内部类和正常类是一模一样的,该定义成员变量,成员方法,构造方法!
        int count; //心脏每分钟跳动的次数

        public void showCount() {
            //内部是可以随意访问外部类的内容的,不重名的情况下可以直接使用名称访问,重名冲突的情况下,默认就近原则(局部/内部类/外部类)
            //使用外部类名.this表示外部类对象,this表示内部类对象
            System.out.println(Person.this.name + "的年龄是" + Person.this.age + "岁,当前心脏每分钟跳动的次数是" + this.count + "次!");
        }

        public Heart() {
            if (age >= 1 && age <= 6)
                this.count = 60;
            else if (age >= 7 && age <= 18)
                this.count = 90;
            else if (age >= 19 && age <= 60)
                this.count = 99;
            else if (age >= 61 && age <= 120)
                this.count = 50;
            else
                this.count = 0;
        }
    }

    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 Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

创建内部类的对象:

外部类名.内部类名 变量名 = new 外部类名().new 内部类名();

Person.Heart heart = new Person("小明", 23).new Heart();

静态内部类

静态内部类就是成员内部类的一种。

静态内部类定义格式:

public class Outer {
    //实例方法
    public void show() {
        System.out.println("Outer的show方法执行了!");
    }

    //静态方法
    public static void function() {
        System.out.println("Outer的静态function方法执行了!");
    }

    //静态内部类
    public static class Inner {
        //内部类的实例方法(需要基于内部类对象调用)
        public void method() {
            function(); //静态内部类可以访问外部类的静态内容,不能访问实例内容
        }
        //内部类的静态方法(基于内部类名来调用)
        public static void staticMethod(){
            function();
        }
    }
}

静态内部类的使用方式:

外部类名.内部类名 变量名 = new 外部类名.内部类名();

//创建静态内部类对象
Outer.Inner i = new Outer.Inner();

i.method();//实例方法
Outer.Inner.staticMethod(); //静态方法

局部内部类

局部内部类的格式:

public class InnerDemo3 {
    public static void main(String[] args) {
        //局部内部类定义在方法中/代码块中/构造方法中(特点:在方法执行过程中必须完成类的声明和类的使用) 鸡肋!
        class A {
            public void show() {
                System.out.println("局部内部类A的实例方法show方法执行了!");
            }
        }
        A a = new A();
        a.show();
    }
}

局部内部类的基本使用:

如果定义在实例方法中,可以访问外部类的所有内容,如果定义在静态方法中,只能访问外部类的静态内容。

匿名内部类

匿名内部类的格式:

new 抽象父类/接口(){
	//针对于抽象父类/接口的方法重写
}

匿名内部类的本质:

本质上抽象父类/接口(){}这个部分就是编写好逻辑的一个子类/实现类,前面的new表示创建一个子类/实现类对象。

总结为一句话:匿名内部类就是指定的抽象父类/接口的子类对象(带有完整实现逻辑)。

匿名内部类的使用前提与快捷方式

(1)当方法的参数是一个接口/抽象父类,快速传递一个带有指定逻辑的子类对象/实现类对象作为参数的时候。

可以考虑匿名内部类。

匿名内部类就是作为一个参数去传递的!

(2)如果抽象父类/接口中的方法过多,不建议使用!由于匿名内部类是一次性的,少量的方法可以用,要实现的方法过多,建议还是新建一个具体的类挨个实现之后提高复用性!

让代码编写更灵活,不需要死板的新建类,实现接口,实现方法,创建对象!

(3)匿名内部类在使用的时候,如果明确要作为哪个抽象父类或者接口的对象,那么直接在传递参数的时候new,根据提示选择即可快速生成!

枚举

枚举:保证一个类的对象是有限的。

枚举的定义格式

public enum 枚举类名 {
	
    枚举项名(对象名),枚举项名(对象名),枚举项名(对象名);
    
    //和其他类一样声明成员方法,成员变量,不建议生成构造方法(默认也是私有的)
}

例子

public enum Season {
    //通过分析明确Season创建4个对象就足够,分别表示春夏秋冬!
    //枚举项一般被static final修饰,也就是常量。
    SPRING, SUMMER, AUTUMN, WINTER;  //public static final Season SPRING = new Season();

    //剩余的部分(和正常类一样) 生成成员变量,生成成员方法。
    public void goWhere() {
        System.out.println("去哪里!");
    }

    //构造不推荐生成(枚举的构造默认是私有的)
}
public class SeasonTest {
    public static void main(String[] args) {
        //获取枚举项之后就作为一个普通对象进行使用。
        Season.SPRING.goWhere();
        //作为参数传递(和多态没有关系)=>当发现方法的参数是枚举的时候,本质上传递的是枚举项(枚举的一个对象)。
        go(Season.SPRING);
        go(Season.SUMMER);
        go(Season.AUTUMN);
        go(Season.WINTER);
    }

    public static void go(Season season) {
        switch (season) {
            case SPRING:
                System.out.println("春天应该去郊游!");
                break;
            case SUMMER:
                System.out.println("夏天应该去游泳!");
                break;
            case AUTUMN:
                System.out.println("秋天应该去吃水果!");
                break;
            case WINTER:
                System.out.println("冬天应该去滑雪!");
                break;
        }
    }
}

当想要获取到枚举类中的某一个枚举项,就按照枚举类名.枚举项名访问即可获取到该对象。

获取到该对象之后,本质上就是个对象,基于对象调用方法、作为参数传递。

枚举单例模式是最安全的单例模式。

枚举的注意事项

(1)枚举类的第一行必须用于声明枚举类的对象的名称,不能干别的。

(2)枚举的构造不需要手动生成,即便生成了默认也是私有的。

(3)枚举类都是最终的不可以继承。

枚举单例模式格式:

public enum Sason{
    SPRING;
}

既能防止之后的反射破坏,也可以防止序列化破坏,也可以在多线程环境下安全(不好点:饿汉式)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值