## 0521Day04内部类

【重点】

Math公式
静态导入
正则表达式
内部类
访问修饰符

【Math】

Math包的相关方法:
	round:四舍五入:-10.9==>-11/-11.2==>-11
	floor:向下取整:10.9==>10/-11.2==>-12
	ceil:向上取整:10.1==>11/-11.2==>-11
	sqrt:开平方根:传入的及返回的是double类型
	pow(x,y):乘方计算

注意事项
Math()构造器为私有,外部无法创建
Math位于lang包下,不导入可以直接带Math使用:Math.abs();
ctrl + shift + o 可以自动导入所有包

【静态导入】

要使用静态成员(方法和变量),必须提供这个静态成员的类。
使用静态导入可以使被导入类的静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名。

【正则表达式】

Pattern p = Pattern.compile("a.b");//匹配正则表达式
Matcher m = p.matcher("ammb");//匹配要校验的字符串
boolean b = m.matches();//判断结果赋值给变量
System.out.println(b);

【内部类】

内部类分类:成员内部类,静态内部类,局部内部类,匿名内部类

作用:
1.内部类可以编译成class文件
2.内部类可直接访问外部类的私有成员属性,而不破坏封装属性
3.为外部类增加必要的功能组件

【成员内部类】

1.在类内部定义,与成员属性、方法同名
2.成员内部类不能脱离外部类存在,创建外部类时才有内部类
3.内外部类有重名属性时,优先访问内部属性
4.成员内部类不能定义静态成员
	静态意味着不需创建对象就能使用,与第二条冲突

【静态内部类】

1.静态内部类与静态成员属性,静态成员方法同级
2.不依赖外部类对象可直接创建内部类对象或直接通过类名访问,可声明静态成员
3.静态方法只能声明在静态内部类或者顶层类中,在非静态内部类中不能定义静态方法和静态属性

【成员内部类/成员内部类代码示例】

// 代码块
package interclass;

import java.io.Serializable;

/**
 * 顶级类只能由public default final abstract修饰
 * 
 * @author GXC
 *
 */
//private class AAA{}
public class Outter01 {
	int local = 100;
	int n1 = 10;
	static int n2 = 20;
	// 以匿名子类的方式创建Object的obj对象,编译后会自动生成一个从1开始的class文件
	private Object obj = new Object() {
	};

	// 以匿名实现类的方式创建Serializable的ser对象,该对象实现了Serializable接口
	// 编译之后自动生成一个以1开始的class文件
	private Serializable ser = new Serializable() {
	};

	// 一个类的内部可以用public实现,不限制修饰符类型
	public class Inner01 {
		int local = 200;
		// i1表示Inner01的内部类成员变量
		int i1 = 100;
		// i2 不能用static来修饰,非静态类不能有静态属性
//		static int i2 = 200;

		public void m1() {
			int local = 300;

			// 外部类成员属性,内部类成员属性,局部变量访问方式
			System.out.println("---------三层变量访问--------");
			System.out.println(local);
			System.out.println(this.local);
			System.out.println(Outter01.this.local);
			System.out.println("---------三层变量访问--------");

			System.out.println("Outter01.Inner01.m1()");
		}

		/**
		 * 静态方法只能被声明在静态类中或者顶层类中 在非静态内部类中不能定义静态的方法
		 */
//		public static void inTest02() {
//
//		}
	}

	/**
	 * 在一个类中可以定义一个静态内部类 静态内部类可以同时包含静态属性方法和非静态属性方法
	 * 
	 *
	 * @author GXC
	 *
	 */
	public static class Inner02 {
		int i1 = 10;
		static int i2 = 20; // 静态变量是斜体字

		void m3() {

		}

		static void m4() {
//			静态方法不能访问非静态成员属性,可以访问静态成员属性
			System.out.println(i2);
		}
	}
}

// 测试类
package interclass;
/**
 * 
 * 概述:成员内部类和静态内部类
 * 
 * 
 * 静态属性,静态方法
 * 非静态属性,非静态方法
 * 
 * 静态属性依赖类,不依赖对象
 * 非静态属性依赖对象
 * 
 * 静态属性在访问时不能确认对象是否存在,存在不确定性
 * 	所以:静态方法只能访问静态属性,不能访问依赖对象的非静态属性(因为不能确认是否对象存在)
 * 		而非静态方法使用时,已经可以确认已经产生了对象,此时非静态方法可以访问非静态属性。
 * 		另外,因为非静态使用时,已经产生了对象,因此“类”也已经存在,所以依赖“类”的静态属性也可以访问 
 * 
 * @author GXC
 *
 */
public class TestOuter01 {
	public static void main(String[] args) {
		
		
		
		Outter01 o = new Outter01();
		System.out.println(o.n1);
		System.out.println(Outter01.n2);
		
		
		// 对于一个类的非静态内部类中的属性与方法的调用,必须先得到外部类对象才可以调用
		// 因为非静态属性和方法依赖于对象,没有对象无法进行访问
		new Outter01().new Inner01().m1();
		System.out.println(new Outter01().new Inner01().i1);
		
		// 静态内部类不依赖外部类,非静态内部类(成员内部类)依赖外部类对象
		
		// 对于静态内部类:可以直接使用【外部类名.内部类名.(静态属性,静态方法)】进行访问
		System.out.println(Outter01.Inner02.i2);
		Outter01.Inner02.m4();
		
		// 对于静态内部类,可以创建静态内部类对象,进而访问静态内部类非静态成员属性和方法
		System.out.println(new Outter01.Inner02().i1);
		new Outter01.Inner02().m3();
		
		// 对于非静态内部类:需要创建外部类对象,再创建内部类对象,进而进行访问
		new Outter01().new Inner01().m1();
		// 【重点】非静态内部类没有静态属性和静态方法
		
		
	}
}

【局部内部类】

1.在外部类方法内部定义,和局部变量是一个级别
2.局部内部类访问外部类当前方法中的局部变量时,因无法保证变量的生命周期与局部内部类相同,变量需修饰为final
	局部变量在方法结束以后就被收回,内部类中的对象实在堆中,伴随垃圾回收周期性回收,还有可能存在类已经结束,但对象还在内存中存在的情况。因此需将局部变量用final修饰,此时该变量会放在常量池中,常量池中的变量回收要求严。

【匿名内部类】

1.匿名内部类时没有名称的局部内部类,其他与局部内部类一致。
2.必须实现一个接口或者继承一个父类。

【局部内部类/匿名内部类代码示例】

package interclass;

/**
 * 局部内部类和匿名内部类
 * 
 * @author GXC
 *
 */
public class Outter02 {
	class Inner01 {
		void test1() {
			System.out.println("Outter02.Inner01.test1");
		}
	}

	public void test() {
		new Inner01().test1();
		System.out.println("---111------");
		new Inner01() {
		}.test1();
		System.out.println("--222-------");
		new Inner01() {
			void test1() {
				System.out.println("匿名对象重写了test1方法");
			}
		}.test1();

		System.out.println("--333-------");

		new Inner01() {
			void test() {
				System.out.println("Inner01.test");
			}

			void test1() {
				System.out.println("Inner01.test1");
			}
		}.test1();// test()方法也可以

		System.out.println("--444-------");

		Inner01 in = new Inner01() {
			void test() {
				System.out.println("Inner01.test");
			}

			void test1() {
				System.out.println("Inner01.test1");
			}
		};

		// 此处只有test01
		in.test1();
		// test()方法不能访问,此时in为父类引用
//		in.test();
	}
}

package interclass;

public class TestOutter02 {
	public static void main(String[] args) {
		new Outter02().test();
	}
}

【内部类对比】

内部类的主要作用是限制类的使用范围

内部类使用范围:
minest:局部内部类:仅有当前局部内部类方法可以访问
==>私有的成员内部类:当前外部类成员方法访问
==>私有的静态内部类:当前外部类成员方法,静态方法
==>公开的成员内部类:创建对象后的方法
==>公开的静态内部类:根据访问修饰符不同的类名访问

【访问修饰符】

private修饰的资源,只能在当前类中被访问
default修饰的资源,只能被同包下其他类访问
protected修饰的资源,可以被同包以及存在继承关系的非同包类访问
public修饰的资源,可以被任何同项目的其他类来访问

【TIPS】

1.Math位于lang包下,不导入可以直接带Math使用:Math.abs();
2.ctrl + shift + o 可以自动导入所有包
3.顶层类只能由public, default, final, abstract修饰://private class AAA{}//错误
4.静态变量是斜体字
原文地址:https://www.cnblogs.com/raising/p/12934582.html