javaSE-内部类

1.概述

当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内 部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使 用内部类

​ 在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者 称为外部类。

​ Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完 整的名称。

​ 内部类最大的优点,可以使用外部类私有化数据

2.分类

1.静态内部类

​ 使用static修饰的内部类,相当于静态变量

2.成员内部类

​ 没有static修饰的位于类体的内部类,相当于成员变量

3.局部内部类

​ 方法中声明的内部类

4.匿名内部类(最常用)

3.静态内部类

public class OutterClass{
    static class InnerClass{
        public static void m1(){
            
        }
        public void m2(){
            
        }
    }
    public static void main(String[] args){
        //当前类中类名可以省略
        OuterClass.InnerClass.m1();
        InnerClass.m1();
        
        InnerClass ic = new OuterClass.InnerClass();
        InnerClass ic1 = new InnerClass();
        ic.m2();//成员属性必须创建对象才能使用
    }
}


注意:

可以使用权限修饰符: private protected public默认

先编译外部类,再编译内部类

类名为:外部类内 部 类 O u t e r C l a s s 内部类 OuterClass内部类OuterClassInnerClass

静态内部类中可以有任何申明(静态和成员都可以)

静态内部类中不能直接访问成员属性(需要有对象)

4.成员内部类

public class OuterClass{
    private static String s1 = "A";
    private String s2 = "B";
    class InnerClass{
        public void m2(){
            public void m2(){
                System.out.println(s1);
                System.out.println(s2);
            }
        }
    }
    public static void main(String[] args){
        //外部类
        OuterClass oc = new OuterClass();
        //创建内部类对象 外部类对象.new内部类();
        InnerClass ic = oc.new InnerClass();
        ic.m2();
    }
}


注意:

可以使用权限修饰符: private protected public默认

先编译外部类,再编译内部类

类名为:外部类内 部 类 O u t e r C l a s s 内部类 OuterClass内部类OuterClassInnerClass

成员内部类不能有静态申明

成员内部类可以访问外部类所有的数据

5.局部内部类

public class OuterClass{
    privaet static String s1 = "A";
    private String s2 = "B";
    public void m1(){
        // 1.8开始 可以不加final修饰,但是值还是不能更改的
         int i = 10;
        class InnerClass{
            // 不能有静态声明
            // public static void m3(){}
            public void m4(){
                System.out.println(s1);
                System.out.println(s2);
                System.out.println(i);
            }
        }
        // 局部内部类的使用,必须在该方法中,因为作用域只在该方法中有效
        InnerClass in = new InnerClass();
        in.m4();
    }
    public static void m2(){

        // 1.8开始 可以不加final修饰,但是值还是不能更改的
         int i = 10;
        class InnerClass{
            // 不能有静态声明
            // public static void m3(){}
            public void m4(){
                System.out.println(s1);
                // 需要对象调用
                // System.out.println(s2);
                System.out.println(new _03_OuterClass().s2);
                System.out.println(i);
            }
        }
        // 局部内部类的使用,必须在该方法中,因为作用域只在该方法中有效
        InnerClass in = new InnerClass();
        in.m4();
    
    }
    public static void main(String[] args) {
        _03_OuterClass oc = new _03_OuterClass();
        oc.m1();

        m2();
    }
}


注意:

局部内部类,访问外部方法的局部变量的时候,该局部变量必须使用final修饰
但是 1.8开始 final 可以省略,但是值依然不能更改

不管是成员方法还是静态方法,都不能使用static修饰局部内部类

不管是成员方法还是静态方法,局部内部类中都不可以声明静态属性

如果是成员方法的局部内部类,则可以直接访问外部类中的所有属性

如果是静态方法的局部内部类,则不能直接访问成员属性,需要有对象

类名 :
如果多个方法的内部类类名不一致,就是 : 外部类$1内部类
如果多个方法的内部类类名一致,就是 : 外部类$1内部类 , 外部类$2内部类 以此类推

6.匿名内部类(最常用)

public class _04_OuterClass {
    public static void main(String[] args) {
        String[] strs = { "123", "22", "321", "14" };
        // 默认排序 会按照ASCII码值进行比较
        // 但是如果我们想按照数值大小排序,就需要自定义规则
        // Arrays.sort(strs);
        // A a = new A();
        // 有一个传入Comparator比较器接口的方法
        // 因为接口不能创建对象,所有需要传入接口类型数据的地方,都需要我们传入该接口对应的实现类对象
        // 若此时这个实现类不经常使用,或者不被其他地方使用,则可以使用匿名内部类
        // Arrays.sort(strs, a);
        Arrays.sort(strs, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                System.out.println(this);
                String s1 = (String) o1;
                String s2 = (String) o2;
                return Integer.parseInt(s1) - Integer.parseInt(s2);
            }
        });
        for (String string : strs) {
            System.out.println(string);
        }
        
        m1(new C());
        m1(new B());
        m1(new B(){
            
        });
    }
    
    public static void m1(B b){
        
    }
}
class B{
    
}
class C extends B{
    
}
// class A implements Comparator{
// @Override
// public int compare(Object o1, Object o2) {
// String s1 = (String) o1;
// String s2 = (String) o2;
// return Integer.parseInt(s1) - Integer.parseInt(s2);
// }
// }



注意:

匿名内部类 : 是指在调用方法的时候,需要传入一个对象(一般是接口的实现类对象),

这个时候就可以不传递对象,传递一个匿名内部类

普通类也可以,一般是接口,匿名内部类 就等于是子类

语法 : 方法名(new 接口名(){ 实现类类体; });

传入匿名内部类的时候,会自动创建一个对象传入,因为没有名字,所以不能复用,我们也不能手动创建对象

类名为 外部类类名$1 , 一次类推

匿名内部类中 不能有静态声明 但是可以有常量(public static final)

入一个对象(一般是接口的实现类对象),

这个时候就可以不传递对象,传递一个匿名内部类

普通类也可以,一般是接口,匿名内部类 就等于是子类

语法 : 方法名(new 接口名(){ 实现类类体; });

传入匿名内部类的时候,会自动创建一个对象传入,因为没有名字,所以不能复用,我们也不能手动创建对象

类名为 外部类类名$1 , 一次类推

匿名内部类中 不能有静态声明 但是可以有常量(public static final)

不能直接访问外部类的成员属性,需要有对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mizui_i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值