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
发出的红包

打赏作者

Antgeek

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

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

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

打赏作者

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

抵扣说明:

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

余额充值