内部类和匿名内部类
1,内部类
什么是内部类
在java中一个类嵌套在另一个类中的这种叫做内部类
class Out { // 外部类
// ...
class Nei { // 嵌套类,或称为内部类
// ...
}
}
按照内部类位置分类
成员位置:在成员位置定义的类,被称为成员内部类。
局部位置:在局部位置定义的类,被称为局部内部类。
1.1、成员内部类
在java中定义在成员位置的另一个类
又可以分为:静态内部类、非静态内部类、私有内部类
访问格式:
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
静态内部类
可以使用 static 关键字定义,静态内部类我们不需要创建外部类来访问,可以直接访问它
class Outer {
int x = 10;
static class Inner {
int y = 5;
}
}
静态内部类的访问
访问方式:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
public class MyTest {
public static void main(String[] args) {
Outer.Inner myInner = new Outer.Inner();
System.out.println(myInner.y);
}
}
注意事项:
- 静态内部类访问的外部类数据必须用静态修饰。
- 成员方法可以是静态的也可以是非静态的。
- 静态内部类无法访问外部类的成员。
非静态内部类
也就是常见的内部类,是一个类中嵌套着另外一个类。 它有访问外部类成员的权限。
注意:
由于内部类嵌套在外部类中,因此必须首先实例化外部类,然后创建内部类的对象来实现
class Outer {
int x = 10;
class Inner {
int y = 5;
}
}
非静态内部类的访问:
public class MyTest {
public static void main(String[] args) {
//Outer.Inner myInner = new Outer().new Inner();
//System.out.println(myInner.y);
//或者
OuterClass myOuter = new OuterClass();
OuterClass.InnerClass myInner = myOuter.new InnerClass();
System.out.println(myInner.y + myOuter.x);
}
}
私有的内部类
内部类可以使用 private 或 protected 来修饰,如果你不希望内部类被外部类访问可以使用 private 修饰符可以保证数据的安全
class Outer {
int x = 10;
private class Inner {
int y = 5;
}
public int showInner(){
Inner inner = new Inner();
return inner.y;
}
}
私有的内部类的访问:
不可以使用普通的方式进行访问否则会报错可以在外部类中定义方法进行访问
1.2,局部内部类
局部内部类是指在一个方法中定义的内部类。
public class Test {
public void method() {
class Inner {
// 局部内部类
}
}
}
- 局部内部类只在当前方法中有效
- 局部内部类中不能定义 static 成员。
- 在局部内部类中可以访问外部类的所有成员。
- 局部内部类访问局部变量必须用final修饰
public class Test {
Inner i = new Inner(); // 编译出错
Test.Inner ti = new Test.Inner(); // 编译出错
Test.Inner ti2 = new Test().new Inner(); // 编译出错
public void method() {
class Inner{
}
Inner i = new Inner();
}
}
可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
2,匿名内部类
匿名类是指没有类名的内部类,必须在创建时使用 new 语句来声明类。
就是局部内部类的简化写法
格式:
new <类或接口>() {
// 类的主体
重写方法;
};
本质:是一个继承了该类或者实现了该接口的子类匿名对象。
特点:
- 匿名类和局部内部类一样,可以访问外部类的所有成员。如果匿名类位于一个方法中,则匿名类只能访问方法中 final 类型的局部变量和参数。
public class Out {
void show() {
System.out.println("调用 Out 类的 show() 方法");
}
}
public static void main(String[] args) {
int a = 10;
final int b = 10;
Out anonyInter = new Out() {
void show() {
// System.out.println("调用了匿名类的 show() 方法"+a); // 编译出错
System.out.println("调用了匿名类的 show() 方法"+b); // 编译通过
}
};
anonyInter.show();
}
2.匿名类中允许使用非静态代码块进行成员初始化操作。
3.匿名类的非静态代码块会在父类的构造方法之后被执行。