1.四种内部类
一个类的内部又完整的嵌套了另一个类的结构,被嵌套的类称为内部类(inner class)
- 内部类的最大特点就是:可以直接访问私有属性,并且可以体现类与类之间的包含关系
内部类的基本语法:
内部类的划分:
2.局部内部类1
局部内部类的特点:
- 局部内部类是定义在外部类的局部位置,通常在方法中
- 局部内部类本质还是一个类,五大成员都可以有(属性,方法,构造器,代码块,内部类)
- 可以访问外部类的所有成员,包括私有成员
- 不能添加访问修饰符,但可以用final修饰(相当于一个局部变量,加了final该类则不可被继承)
- 作用域:仅仅在定义它的方法或代码块中(相当于一个局部变量)
- 局部内部类访问,外部类成员的方式:直接访问
- 外部类访问,局部内部类成员的方式:创建局部内部类对象
3.局部内部类2
外部类和局部内部类的成员重名时,访问外部类成员的方法(外部类名.this.成员)。外部类名.this,指的是外部类的对象,直接用this则是内部类的对象
局部内部类细节:
4.匿名Anonymous内部类的本质,基于接口的匿名内部类使用
匿名内部类:
- 本质还是一个类
- 内部类
- 没有名字(匿名内部类的名字由系统分配)
- 同时还是一个对象
匿名内部类简化开发:只使用一次的类,写成匿名内部类
匿名内部类的运行类型就是:外部类名$1(基于接口的匿名内部类)
- 匿名内部类的编译类型是什么
- 匿名内部类的运行类型是什么
jdk底层在创建匿名内部类时,立即就创建了匿名内部类的实例,并把地址返回给对象引用
匿名内部类使用一次,就不能再使用了,但接收匿名内部类实例的对象引用tiger,可以反复调用
5.匿名内部类的使用,基于类的匿名内部类使用
基于类的匿名内部类使用:
- 编译类型是什么
- 运行类型是什么:外部类名$2(基于类的匿名内部类,数字是系统自动顺序编号的)
底层创建匿名内部类:可以重写该类中的方法
同时也直接返回了匿名内部类的对象:
- 参数列表("Jack")会传递给Father类的构造器
基于抽象类的匿名内部类,必须实现抽象类中的方法
6.匿名内部类的细节
匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征
- 两种调用匿名内部类的方法
系统自动创建匿名内部类,继承了Person,所以super.ok(str),调用的就是Person类中的ok方法(多态)
匿名内部类使用细节:
7.匿名内部类实践
匿名内部类最佳实践:当作实参直接传递,简洁高效(只用一次)
传统方法-硬编码,创建一个类实现接口,然后通过new创建实例调用
练习题:传递一个匿名内部类,根据传进内部类的不同,打印不同信息
答案:编译类型是Bell,运行类型是变化的(动态绑定)
匿名内部类的难点:
8.成员内部类1
- 成员内部类定义的位置,在外部类的成员(属性方法)位置
- 可以添加任意的访问修饰符,因为它的地位就是一个成员
9.成员内部类2
外部其他类也可以访问成员内部类——三种方法:
方式一:将成员内部类当成外部类的一个成员进行调用/实例化
方式二:在外部类中定义一个方法,返回成员内部类实例
方式三:方式一与二结合(会前两种即可)
外部类与成员内部类成员重名问题:就近原则,
- 可以通过 外部类名.this.属性 的方式来访问外部类成员
10.静态内部类1
- 静态内部类,定义在外部类成员位置,有static修饰
- 静态内部类只能访问静态成员
- 可以添加任意的访问修饰符
- 作用域为整个类体
11.静态内部类2
- 静态内部类的属性访问问题:
- 外部其他类访问静态内部类的方式:
方式一:通过 类名. 直接访问(前提是满足访问权限)
方式二:编写一个方法,返回静态内部类的对象实例(非静态方法)
方式三:将方式二中的方法改为静态的(静态方法)
静态内部类成员重名问题
小结:
12.练习
能否输出的问题:查看访问权限