内部类概念
在一个类的内部定义一个完整的类
特点:
- 在编译后可生成独立的字节码文件
- 内部类可直接访问外部类的私有成员,而不破坏封装
- 可为外币类提供必要的内部功能组件
- 可以实现类的私有化
成员内部类的使用
在外部类中,创建对象在使用
在其他类中使用:
- 保证内部类的访问权限足够
- 先创建外部类的对象 ,再创建内部类的对象,因为成员内部类依赖外部类对象
- 内部类与外部类变量访问问题:
- 成员内部类可以方法外部类的实例变量
- 成员内部类可以访问外部类的静态变量 - 成员内部类不能定义静态属性
public class Car {
String name;
Engine engine = new Engine();
public Car(String name) {
this.name = name;
}
public Car() {
}
public void start(){
engine.fire();
}
class Engine{
private void fire(){
String name = "V8";
System.out.println(Car.this.name+"启动了");
}
}
}
public class TestCar {
public static void main(String[] args) {
Car car = new Car("宝马");
car.start();
}
}
静态内部类
- 不依赖外部类,可以直接创建或通过类名访问,可以声明静态成员
- 只能直接访问外部类的静态成员(实例成员需实例化外部类对象)
package com.day13.qfedu.ch2;
public class OuterClass {
static int ox = 200;
int oy = 110;
static class Inner {
static int ix = 100;
int iy = 119;
int ox = 10;
static int i = OuterClass.show();
public static void showX() {
System.out.println(ix +"\t" + OuterClass.ox);
}
public void showIy() {
System.out.println(iy);
}
}
public static int show() {
System.out.println(Inner.ix);
Inner.showX();
Inner inner = new Inner();
inner.showIy();
return inner.iy;
}
}
package com.day13.qfedu.ch2;
public class TestStaticInnerClass {
public static void main(String[] args) {
OuterClass obj = new OuterClass();
obj.show();
System.out.println(OuterClass.Inner.ix);
OuterClass.Inner obj2 = new OuterClass.Inner();
obj2.showIy();
obj2.showX();
OuterClass.Inner.showX();
System.out.println(OuterClass.Inner.i);
}
}
如何使用静态内部类:
1.在外部类中使用静态内部类:
使用静态内容,直接类名调用,使用尘缘内容,通过对象调用
2. 静态内部类不可以风闻外部类的实例属性,实例方法,可以访问静态属性和静态方法
外部类访问内部类使用静态内容,直接类名调,使用成员内容,通过对象调用
3. 内部类访问外部类同名的静态变量,优先访问自己的,访问外部的通过 外部类.变量
加载外部类时,不会加载静态内部类
加载静态内部类时,奴会加载外部类
局部内部类
- 定义在外部类方法中的内部类,作用范围和创建对象范围仅限于当前方法。
- 局部内部类访问外部类当前方法中的局部变量时,因为无法保障变量的生命周期与自身(内部类)相同,变量必须用final修饰
- 局部内部类变量的生命周期为方法结束 - 限制类的使用范围
如何使用:
- 局部内部类的使用别局限在方法中,先创建其对象访问属性和方法。
如何区分
- 默认情况下按就近原则
- this.变量 (外部类的成员变量)
- 外部类.this.变量 (外部类的成员变量)
public class LocalInnerClass {
int age = 11;
public void test(){
int bnnum = 33;
class Inner{
int age = 22;
public void print(){
int age = 44;
System.out.println(age);
}
}
Inner inner = new Inner();
inner.print();
}
}
public class TestLocal {
public static void main(String[] args) {
LocalInnerClass localInnerClass = new LocalInnerClass();
localInnerClass.test();
}
}
匿名内部类
- 没有类名的局部内部类(一切特征与局部类相似)
- 必须继承一个父类或实现一个接口
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
代码写法的一种方式,把类的编写和创建合二为一
package com.day13.qfedu.ch5;
public class TestAnonymousClass {
public static void hobby(IHobby hobby){
hobby.shoe();
}
//入口
public static void main(String[] args) {
hobby(
new IHobby() {
@Override
public void shoe() {
System.out.println("打球");
}
}); System.out.println("=============================");
IHobby obj = new IHobby() {
@Override
public void shoe() {
System.out.println("大羽毛球");
}
};
obj.shoe();
System.out.println("=============================");
new IHobby(){
@Override
public void shoe() {
System.out.println("xxx");
}
}.shoe(); System.out.println("=============================");
hobby(()->{
System.out.println("dd");
});
}
}
interface IHobby{
void shoe();
}
可用于优化接口的回调
- 有点:减少代码量
- 缺点:可读性较低