Java 中的 内部类和枚举类

内部类

成员内部类

可以直接在类的内部定义成员内部类

一般只会在类的内部自己使用

public class Person {
    protected String name; //子类需要,但是外部不允许访问
    protected int age;
    protected String sex;

    public class Inner {
        public void test(int a,int b,String... strings) {
            System.out.println(name); //内部类可以访问外部的成员变量
    }
 }

创造类

public static void main(String[] args) {
        Person person = new Person();
        Person.Inner inner = person.new Inner(); //在person里面创造Inner类
    	inner.test();
    }

成员内部类也可以使用访问权限控制,如果我们我们将其权限改为private,那么就像我们把成员变量访问权限变成私有一样,外部是无法访问到这个内部类的

变量的调用

public class Person {
    protected String name = "outside"; //子类需要,但是外部不允许访问
    protected int age;
    protected String sex;

    public class Inner {
        String name = "inner";
        public void test() {
            System.out.println("方法的参数的name是 = "+name); //就近原则
            System.out.println("成员内部类的name= "+this.name); //在内部类中使用this关键字,只能表示内部类的对象
            System.out.println("成员内部类的name= "+Person.this.name); //要指定为外部对象,则需要在前面加上外部类名称
        }
    }
}

输出

方法的参数的name是 = inner
成员内部类的name= inner
成员内部类的name= outside

调用函数

public class Inner {

    String name;
    public void test(String name){
        this.toString();		//内部类自己的toString方法
        super.toString();    //内部类父类的toString方法
        Test.this.toString();   //外部类的toSrting方法
        Test.super.toString();  //外部类父类的toString方法
    }
}

静态内部类

静态内部类就像静态方法和静态变量一样,是属于类的

创建方法

不需要依附于任何对象,可以直接创造静态内部类的对象

public static void main(String[] args) {
        Person.Inner inner = new Person.Inner();
        inner.test();
    }

访问

静态内部类是无法访问到外部类的非静态内容的,受影响的只是外部内容的使用,内部不受影响,跟普通的类一样

原因:静态内部类属于外部类,不依附任何对象,如果直接访问外部类不知道应该访问哪个对象

在这里插入图片描述

public static class Inner {
        String name;
        public void test() {
            System.out.println("我是静态内部类!"+name); //此时因为是内部类的所以就可以正确使用
        }
    }

局部内部类

类似于局部变量,在方法中创建

既然是在方法中说明的类,那么作用范围也就是在方法里

public void hello() {
        class Inner { //类似于局部变量,先声明,后使用
            public void test() {
                System.out.println("我是局部内部类");
            }
        }
        Inner inner = new Inner(); //局部内部类就直接使用类名就可以
        inner.test();
    }

匿名内部类

是局部内部类的简化版

在抽象和接口中都会含有某些抽象方法需要子类去实现,不能直接通过new的方法来创造一个抽象类或者是接口对象,但是可以使用匿名内部类

创建

public abstract class Workers {
    public abstract void test();
}

抽象类使用

此时创建出来的Workers的对象,已经实现了抽象方法的抽象,这个抽象直接就定义好了,连名字都没有。就可以直接创造出对象

匿名内部类中同样可以使用类中的属性(因为它本质上就相当于是对应类型的子类)

    public static void main(String[] args) {
        Workers worker = new Workers() {
            int a;
            @Override
            public void test() {
                System.out.println("我是匿名内部类!");
            }
        };
        worker.test();
    }

接口使用

同样的,接口也可以通过这种匿名内部类的形式,直接创建一个匿名的接口实现类:

public static void main(String[] args) {
    Study study = new Study() {
        @Override
        public void study() {
            System.out.println("我是学习方法!");
        }
    };
    study.study();
}

并不是只有抽象和接口才可以像这样创造匿名内部类,普通的类也可以,但是意义不大

Lambda表达式

创建一个临时的实现子类

条件:如果接口当中有且只有一个待实现的抽象方法,那么我们可以将匿名内部类简写成 Lambda表达式

标准格式为:([参数类型 参数名称,]...) ‐> { 代码语句,包括返回值 }

enum枚举

例如我们要为一个人设定一个状态,如果都是外部传入,则会不靠谱,因此不如自己内定

创建

可以为枚举类增加构造器、方法和字段
构造器只是在构造枚举常量的时候使用,且为私有,可以省略private 修饰符

    public enum status { //enum表示是一个枚举类
        RUNNING, STUDY, SLEEP; //后面的分号可以不打,建议打上
    }

使用

private Status status;   //类型变成刚刚定义的枚举类

public Status getStatus() {
    return status;
}

public void setStatus(Status status) {
    this.status = status;
}

如此,别人在使用的时候,就能直接清楚我们知道什么

在这里插入图片描述

枚举类型本质就是一个普通的类,但是它继承自Enum类,我们定义的每一个状态都是 public static final 的status类型成员变量

//这里使用javap命令对class文件进行反编译得到 Compiled from "Status.java"
public final class com.test.Status extends java.lang.Enum<com.test.Status> {
  public static final com.test.Status RUNNING;
  public static final com.test.Status STUDY;
  public static final com.test.Status SLEEP;
  public static com.test.Status[] values();
  public static com.test.Status valueOf(java.lang.String);
  static {};
}

成员方法

既然枚举类型是普通的类,那么我们也可以给枚举类型添加独有的成员方法:
比较枚举类的值,可以直接使用==,而不需要equals()

    public enum status { //enum表示是一个枚举类
        RUNNING("跑步"), STUDY("学习"), SLEEP("睡觉"); //后面的分号可以不打,建议打上
        private final String name;

        status(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }

使用

    public static void main(String[] args) throws CloneNotSupportedException {
        Workers workers =new Workers("x",12,"s");
        workers.setStatus(Workers.status.SLEEP);
        System.out.println(workers.getStatus().getName());
    }

输出

睡觉

一些常用方法

Size.SMALL.toString();
Size s = Enum.valueOf(Size.class, “SMALL”);
//静态方法,返回包含全部枚举值的数组
Size[] values = Size.values();
//返回枚举常量在Enum声明中的位置,从0开始计数
int ordinal();
//出现在other之前,返回负数,相同位置则返回0,否则为正整数
int compareTo(E other);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值