内部类 匿名内部类

分享下匿名内部类的案例:

内部类的访问规则

/**
 * 内部类的访问规则
 * 1.内部类可以直接访问外部类的成员,包括私有
 * 2.外部类访问内部类,必须建立内部类的对象
 * 3.之所以内部类可以访问外部类,因为内部类中,持有外部类的引用,
 * 			格式: 外部类名.this
 *
 * @author  mahao
 * @date:  2019年2月14日 下午1:10:55
 */
public class InnerClassDemo {
	
	public static void main(String[] args) {
		Out out = new Out(); 
		out.method();
		
		//直接获取内部类对象
		Out.Inner in = new Out().new Inner();
		in.function();
	}
}


/**
 * 外部类
 */
class Out{
	
	//外部类属性
	private String name = "外部类名字";
	
	/**
	 *内部类
	 */
	class Inner{
		//3.当内部类和外部类有相同属性时,要用this的使用
		private String name = "内部类名字";
		
		//1.内部类可以直接访问外部类成员
		public void function() {
			String name = "名字";
			
			System.out.println("不加this,默认访问方法里面的变量,如果没有,则搜索成员变量:---"+name);
			System.out.println("this在这里,是指Inner对象,所以指的是内部类属性:---"+this.name);
			System.out.println("内部类访问外部类属性,通过外部类名.this:---"+Out.this.name);


		}
	}
	
	//2.外部类访问内部类,必须先有内部类对象
	public void method() {
		Inner inner = new Inner();
		inner.function();
	}
	
	
}

静态内部类访问规则

/**
 ******** 内部类的访问规则
 * 1.内部类可以直接访问外部类的成员,包括私有
 * 2.外部类访问内部类,必须建立内部类的对象
 * 3.之所以内部类可以访问外部类,因为内部类中,持有外部类的引用,
 * 			格式: 外部类名.this
 *
 *****静态内部类访问规则
 *	1.当内部类位于成员变量是时,可以被修饰符修饰,比如内部类私有
 *	2.当内部类被static修饰时,访问外部类的成员必须也是静态的,因为静态内部类先于对象存在,所以必须访问静态的
 *	3.访问静态内部类中的非静态成员,(获取静态内部类对象)
 *		Out.Inner in = new Out.Inner();
 *	4.外部类访问静态内部类中的成员, 内部类名.静态成员属性
 *
 *总结(2019/07/31):对于静态内部类,就相当于创建了一个新的类,内部类与外部类
 *	没有什么关系,这时候静态内部类就是一个普通的类,访问外部类的属性和方法,必须先创建
 *	对象。
 *
 * @author  mahao
 * @date:  2019年2月14日 下午1:10:55
 */

/**
 * 外部类  cesi 
 */
class Out1{
	
	static String name = "外部类属性";
	
	String fiel = "普通属性";
	
	//外部类访问静态内部类中的非静态属性
	public void method() {
		System.out.println("外部类访问静态内部类中的静态成员----"+Inner.name);
	}
	
	
	/**
	 *内部类
	 */
	 static class Inner{
		
		static String name = "内部类属性";
		
		public void function() {
			System.out.println("静态内部类只能访问外部静态成员变量------"+Out1.name);
			System.out.println("静态内部类访问外部类普通成员变量-------"+new Out1().fiel);
		}
	}
	
}


public class InnerClassDemo2 {
	
	public static void main(String[] args) {
		//获取静态内部类中的对象
		Out1.Inner in = new Out1.Inner();
		in.function();
		
		Out1 out = new Out1();
		out.method();
	}
	
}

内部类定义在方法中

/**
 *内部类不在成员属性上,内部类定义在局部时,即定义在方法里面
 *
 *	1.不可以被成员修饰符修饰
 *	2.内部类可以直接访问外部类中的成员变量,因为还持有外部类中的引用
 *		但是访问方法里面的变量,只能被final修饰才可以
 */

/**
 * 外部类
 */
class Out2{
	
	private String name = "外部类属性";
	 
	public void method() {
		
		final int x =3;
		
		/**
		 *定义在方法上的内部类
		 */
		  class Inner{
			
			public void function() {
				//1.內部類可以訪問外部類的屬性
				System.out.println(name);
				//2.内部类访问的局部变量必须被final修饰
				System.out.println(x);
			}
			
		}
		  //方法里面创建内部类,并调用里面的方法
		new Inner().function();
	}
	
	
}


public class InnerClassDemo3 {
	
	public static void main(String[] args) {
		Out2 out = new Out2();
		out.method();
	}
	
}

匿名内部类

/**
 * 匿名内部类
 * 
 * 1.匿名内部类是对内部类的简写形式<br>
 * 2.内部类必须有接口或者父类
 *
 * @author mahao
 * @date: 2019年2月14日 下午7:39:22
 */
public class InnerClassDemo4 {

	public static void main(String[] args) {
		Out4 out = new Out4();
		out.function2();
	}

}

interface IN {
	void method();
}

/** 外部类 */
class Out4 {

	private String name="外部类属性";
	/** 内部类 */
	class Inner implements IN {
		@Override
		public void method() {
			System.out.println("方法执行......");
			System.out.println("内部类访问外部类属性---"+Out4.this.name);
					
		}
	}

	// 外部类成员变量方法
	void function() {
		Inner in = new Inner();
		in.method();
	}

	// 用匿名内部类简写为
	void function2() {
		// Inner in = new Inner();
		// in.method();
		final String methodName = "方法内的变量名";
		
		/**
		 * 匿名内部类的格式
		 */
		new IN() {

			@Override
			public void method() {
				System.out.println("方法执行2......");
				System.out.println("访问外部类属性---"+Out4.this.name);
				System.out.println("访问方法的局部变量---" + methodName);
			}

		}.method();
		
		/*//反编译的结果,给匿名内部类生成了一个新的字节码文件,命名是Out4$1表示,Out4类中的第一个匿名内部类,
		 * 可以看到Out4$1中含有Out4的对象的引用this$0,获取外部类的属性都是通过这个引用。
		 * 对于方法中的局部变量,为什么要声明为final类型,是因为内部类中使用方法中的局部变量,是通过直接拷贝变量的值,
		 * 到内部类中去使用,如果局部变量的值,会发生改变,还有是保证声明周期。
		 * 
		class Out4$1 implements IN {
		    Out4$1(Out4 var1) {
		        this.this$0 = var1;
		    }
		
		    public void method() {
		        System.out.println("方法执行2......");
		        System.out.println("访问外部类属性---" + Out4.access$0(this.this$0));
		        System.out.println("访问方法的局部变量---方法内的变量名");
		    }
		}

		 */
	}
}

代码中都有讲解,可以将代码粘贴出来,在IDE中运行一下,分析它的运行结果。java提供的内部类机制,本质是java的语法糖,和foreach,拆装箱所属一样,是为了简化操作,这些语法糖在编译期间将会被编译器‘解语法糖’,查看反编译之后的结果,更容易解答,匿名内部类粘贴出来了反编译后的结果。
源码练习地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值