第五章 内部类
5.1 内部类
内部类 : 了解
类中定义类
外部类 内部类
分类:
成员内部类
私有内部类
静态内部类
局部内部类
匿名内部类 : 重点
1、成员内部类
成员内部类
- 内部类定义在外部类的成员位置
- 具有类的特点 可以继承其他父类 实现其他接口
- 具有成员的特点 可以被成员修饰符修饰
注意:
- 成员内部类中不能定义静态内容 除了静态的常量
- 成员内部类中可以直接使用外部类的成员 包括私有的
- 外部类中可以通过成员内部类的对象调用成员内部类的成员
- 通过外部类对象去创建成员内部类的对象 通过成员内部类对象调用成员内部类的成员
package wang;
public class Inner {
//成员:类中方法外
//成员变量
private int i=1;
static int j=2;
//成员内部类
public class Inner01{
// 成员变量
int a=100;
static final int b=200;
// 成员方法
public void testInner01(){
System.out.println(i);
System.out.println(j);
System.out.println(a);
System.out.println(b);
}
}
// 成员方法
public void outer(){
Inner01 sc=new Inner01();
System.out.println(sc.a);
}
}
package wang;
//测试类
public class Over {
public static void main(String[] args) {
// 测试使用成员内部类中的成员
Inner sd=new Inner();
Inner.Inner01 sf=sd.new Inner01();
sf.testInner01();
}
}
2、区分同名变量问题
package wang;
//区分同名变量问题
public class Inner {
int i=1;
static int b=5;
class Inner01{
int i=2;
public void test(){
int i=3;
// 调用外部类成员变量i=1
System.out.println(Inner.this.i);
// 调用内部类的成员变量i=2
System.out.println(this.i);
// 调用局部变量i
System.out.println(i);
}
}
}
package wang;
//测试类
public class Over {
public static void main(String[] args) {
Inner.Inner01 sc=new Inner().new Inner01();
sc.test();
}
}
3、私有内部类
私有内部类:
- 被private关键字修饰的成员内部类
- 私有内部类中可以直接使用外部类的成员,包括私有的
- 在外部类中通过私有内部类的对象调用私有内部类的成员,包括私有的
- 私有内部类只能在当前外部类中使用,其他类中无法使用
package wang;
public class Class004_Outer {
private int i = 1;
private static int j = 2;
//私有内部类
private class Inner{
private int a = 100;
private static final int b = 200;
public void test(){
System.out.println("私有内部类的成员方法");
System.out.println(a);
System.out.println(b);
System.out.println(i);
System.out.println(j);
}
}
//外部类的成员方法
public void outer(){
Inner in = new Inner();
System.out.println(in.a);
in.test();
}
}
4、静态内部类
静态内部类
- 静态内部类中可以定义静态内容
- 在静态内部类中可以直接使用外部类的静态内容 需要通过外部类对象使用外部类的成员
- 在外部类中可以通过静态内部类的类名调用静态内部类的静态内容 可以通过静态内部类的对象调用其成员内容
- 在其他类中可以通过外部类类名找到静态内部类 new 静态内部类对象访问其成员 通过静态内部类类名方法其静态内容
- Class005_Outer.Inner in3 = new Class005_Outer.Inner();
public class Class005_Outer {
private int i = 1;
private static int j = 2;
//静态内部类
static class Inner{
int a = 100;
static int b = 200;
//成员方法
public void test(){
System.out.println(b);
System.out.println(a);
System.out.println(j);
System.out.println(new Class005_Outer().i);
}
//静态方法
public static void testStatic(){
Inner in = new Inner();
System.out.println(in.a);
System.out.println(b);
System.out.println(new Class005_Outer().i);
System.out.println(j);
}
}
//外部类的成员方法
public void outer(){
System.out.println(Inner.b);
Inner.testStatic();
new Inner().test();
}
}
5、局部内部类
- 定义在局部位置
- 局部内部类中可以定义成员内容 不可能定义静态内容除了静态的常量
- 只能在局部内部类所在的方法中通过对象访问成员
- 在局部内部类中可以使用所在方法中的局部变量 可以使用外部类的成员
- 如果在局部内部类中使用所在方法中的局部变量(参数) 要求局部变量被final修饰 如果jdk1.8以上版本默认被final修饰
public class Class006_Outer {
String str = "外部类str";
public void test(int i){
//局部
//int i = 1;
//局部内部类
class Inner{
int a = 100;
static final int b = 200;
public void testInner(){
System.out.println("局部内部类的成员方法");
System.out.println(i);
System.out.println(str);
}
}
//i = 6;
System.out.println(Inner.b);
Inner in = new Inner();
System.out.println(in.a);
}
}
6、匿名内部类
匿名内部类 :
- 作用 : 简化实现类|子类,没有自己类本身作用的实现类|子类
匿名内部类对象 :
- 实现类|子类+创建对象
new Smoke(){ //实现类类体|抽象类的子类类体
@Override
public void smoking() {
System.out.println(“边吸烟边吐烟圈…”);
}
}
public class Class007_Outer {
public static void main(String[] args) {
//实现类对象
Demo demo = new Demo();
demo.smoking();
//匿名内部类对象
//1. 匿名对象 : 只能在当前位置使用一次
new Smoke(){ //实现类的类体 | 匿名内部类的类体
@Override
public void smoking() {
System.out.println("一边打游戏一边吸烟...");
}
}.smoking();
//2.引用指向匿名内部类对象
//接口多态 : 接口引用调用的为接口中定义的成员
Smoke s = new Smoke(){
@Override
public void smoking() {
System.out.println("一边上课一边抽烟");
}
};
s.smoking();
s.smoking();
s.smoking();
//3.匿名内部类对象作为方法的实参
test(new Smoke() {
@Override
public void smoking() {
System.out.println("xxxxxxxx");
}
});
}
public static void test(Smoke smoke){
smoke.smoking();
}
}
interface Smoke{
void smoking();
}
class Demo implements Smoke{
@Override
public void smoking() {
System.out.println("边吸烟边吐烟圈...");
}
}
5.2 Lambda 表达式
lambda表达式
作用 : 简化匿名内部类对象
前提 : 函数式接口
函数式接口 : 接口中只有一个必须被重写的抽象方法
强制检查是否为函数式接口 : @FunctionalInterface
语法 : ()->{}
- () : 接口中抽象方法的参数列表
- -> : lambda符号|箭头函数
- {} : 重写方法的方法体
public class Class001_Lambda {
public static void main(String[] args) {
//匿名内部类
/*Swim s = new Swim(){
@Override
public void swimming() {
System.out.println("一边喝水一边游泳...");
}
};*/
//Lambda写法1 : ()->{}
/*Swim s = ()->{
System.out.println("一边换气一边游泳...");
};*/
//Lambda写法2 : 如果方法体语句只有一句,前后的{}可以省略
//Swim s = ()->System.out.println("一边嘻嘻笑一边游泳...");
//Lambda写法3 : 如果方法存在参数,参数的类型可以省略
// Swim s = (name,age)->System.out.println(name+"一边嘻嘻笑一边游泳...");
//Lambda写法4 : 如果参数只有一个,前后的()可以省略
//Swim s = name->System.out.println(name+"一边嘻嘻笑一边游泳...");
//Lambda写法5 : 如果lambda体语句只有一句,并且为return语句,前后的{}与return关键字可以一起省略
Swim s = age->age>18;
System.out.println(s.swimming(18));;
}
}
@FunctionalInterface
interface Swim{
boolean swimming(int age);
//void drinkWater();
}
interface Run{
void run();
}