目录
概念
定义在类内部的类
作用
打破封装,又不破坏封装
分类
-
成员内部类
-
静态内部类
-
局部内部类
-
匿名内部类
成员内部类
位置
与外部类中的属性和方法平级, 是外部类的实例组成之一,相当于特殊的成员方法
语法
访问修饰符 class 外部类类名{ //属性 //方法 访问修饰符 class 内部类类名{ } }
使用
-
静态内容和非静态内容都可以定义和访问
-
低版本的JDK中不允许定义静态内容
-
-
当外部类非静态属性,内部类非静态属性,内部类局部变量重名时:
-
局部变量: 直接获取
-
内部类非静态属性:
this.属性名
-
外部类非静态属性:
外部类类名.this.属性名
-
-
成员内部类对象的创建需要基于外部类对象
外部类类名.内部类类名 对象名=外部类对象名.new 内部类类名();
package com.by.entity; /** * 外部类- 成员内部类 */ public class Outer1 { String str = "外部类的非静态属性"; int num = 100; static int num2 = 200; static String s = "外部类的静态属性"; //成员内部类 public class Inner1{ String str = "内部类的非静态属性"; static String s = "内部类的静态属性"; public void method(){ String str = "这是内部类的局部变量"; System.out.println(num); System.out.println(num2); System.out.println(str);//这是内部类的局部变量 System.out.println(this.str);//内部类的非静态属性 System.out.println(Outer1.this.str);//外部类的非静态属性 System.out.println(Outer1.s);//外部类的静态属性 System.out.println(Inner1.s);//内部类的静态属性 System.out.println(s);//内部类的静态属性 } } }
package com.by.test; import com.by.entity.Outer1; public class Test1 { public static void main(String[] args) { //创建外部类对象 Outer1 o1 = new Outer1(); //创建内部类对象 Outer1.Inner1 inner1 = o1.new Inner1(); inner1.method(); } }
静态内部类
位置
与成员内部类一致, 是外部类的静态组成之一,相当于特殊的静态方法
语法
访问修饰符 class 外部类类名{ //属性 //方法 访问修饰符 static class 内部类类名{ } }
使用
-
无法访问非静态内容
-
可以定义非静态内容, 但是通常属性和方法都建议声明为静态的
-
静态内部类对象的创建只需借助外部类类名
外部类类名.内部类类名 对象名=new 外部类类名.内部类类名();
-
静态内部类中的静态内容可以直接通过
外部类类名.内部类类名.静态内容
的方式访问
package com.by.entity; /** * 外部类- 静态内部类 */ public class Outer2 { String str = "这是外部类非静态属性"; static String s = "这是外部类静态属性"; //静态内部类 static public class Inner2{ static String s = "这是内部类静态属性"; public static void method(){ //System.out.println(str); 报错 System.out.println(Outer2.s);//这是外部类静态属性 System.out.println(s);/ } } }
package com.by.test; import com.by.entity.Outer1; import com.by.entity.Outer2; public class Test2 { public static void main(String[] args) { //创建内部类对象 Outer2.Inner2 inner2 = new Outer2.Inner2(); inner2.method(); //直接访问静态方法 Outer2.Inner2.method(); } }
局部内部类
位置
外部类的方法内部, 相当于特殊外部类的局部变量
语法
访问修饰符 class 外部类类名{ 修饰符 返回值类型 方法名(形参列表){ class 内部类类名{ } } }
使用
-
无法给类添加访问修饰符
-
作用范围: 与局部变量一致
-
只能在所属方法内使用
-
外部类方法可以访问使用的内容局部内部类也一致
-
可以访问外部类中同级的局部常量
-
JDK7.0前: 必须是通过final修饰的局部常量
-
JDK7.0后: 只要是未二次更改值的事实常量即可
-
package com.by.entity; /** * 外部类- 局部内部类 */ public class Outer3 { String str = "外部类非静态属性"; static String s = "外部类静态属性"; //外部类方法 public void ma(){ System.out.println(str); System.out.println(s); String string1 = "这是外部类方法ma中的局部变量"; //string1 = "这是在更改局部变量的值"; //局部内部类 class Inner{ public void method(){ System.out.println(str); System.out.println(s); System.out.println(string1); } } //创建内部类对象 Inner i = new Inner(); i.method(); } }
匿名内部类
位置
写在创建实现类|子类对象的位置
语法
接口名|父类类名 对象名=new 接口名|父类类名(){ //类的内容 };
特点
将类的声明,方法的定义,对象的创建三合一
作用
创建一个实现类|子类对象
使用
-
必须实现自某个接口|继承自某个父类
-
匿名内部类只能创建一次对象
-
可以定义独有内容, 只能在本类内部使用
-
只有一个默认的无参构造, 无法显式定义构造
-
匿名内部类可以是成员状态|局部状态
-
类内部无法使用外部的局部累加器|局部标识变量
lambda表达式
JDK8.0新特性
接口的分类:
标记式接口: 接口中无内容
常量式接口: 只声明了属性, 未定义方法
函数式接口: 只有一个需要重写的方法
普通接口: 拥有多个需要重写的方法
lambda表达式只能作用于函数式接口
作用
为函数式接口创建一个实现类对象
语法
(形参列表)->{ //方法的操作语句 } 通过多态引用接收: 接口名 引用名=(形参列表)->{ //方法的操作语句 };
简化标准
-
参数列表的数据类型可省(同步)
-
参数只有一个时, 小括号可省
-
操作语句只有一条时, 大括号可省
-
操作语句只有一条并且为return语句时, 大括号和return关键字都可省(同步)
public interface Interface2 { void m3(int n);//判断参数是否为偶数并输出 }
public interface Interface3 { int m4(int a,int b);//计算参数之和并返回 }
public interface Interface4 { boolean m5(int n);//判断参数是否为偶数并返回 }
public class Test5 { public static void main(String[] args) { //通过lambda表达式创建接口2的实现类对象 Interface2 i2 = n -> System.out.println(n % 2 == 0 ? "偶数" : "奇数"); i2.m3(20); //接口3 Interface3 i3 = (c, d) -> c + d; System.out.println(i3.m4(10,20)); //接口4 Interface4 i4 = n -> n % 2 == 0; System.out.println(i4.m5(21)); } }