一、什么叫内部类
把类定义在其他类的内部,这个类就被称为内部类。
内部类只是一个编译时的概念,一旦编译成功之后,外部类和内部类就会变成两个不同的类,分别是Outer.class和Outer&Inner.class。所以内部类的成员变量/方法名可以和外部类的相同。
二、内部类访问特点
- 内部类访问外部类:可以直接访问,包括内部类的私有;
- 外部类访问内部类:通过创建对象访问(非静态),通过类名访问(静态)。
class OuterClass {
private int num = 0;
public void outerMethod() {
System.out.println(num);
new InnerClass().innerMethod(); //通过创建对象访问
new InnerClass2().innerMethod();//通过创建对象访问
InnerClass3.innerMethod(); //通过类名访问
}
class InnerClass {
int num1 = 1;
public void innerMethod() {
System.out.println(num);//内部类访问外部类,直接访问
System.out.println(num1);
}
}
static class InnerClass2 {
int num2 = 2;
public void innerMethod() {
System.out.println(num2);
}
}
static class InnerClass3 {
static int num3 = 3;
public static void innerMethod() {
System.out.println(num3);
}
}
}
注意:内部类访问外部类成员是可以使用OutClass.this.外部类成员,(主要用于同名成员的访问)。
例如:
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num); //30
System.out.println(this.num); //20
System.out.println(Outer.this.num); //10
}
}
}
三、内部类位置
- 成员位置:成员内部类;
- 局部位置:局部内部类。
class Outer {
int num = 0;
//成员内部类
class Inner{
int num1 = 1;
public void method() {
System.out.println(num1);
}
}
public void method() {
//局部内部类
class Inner2 {
int num2 = 2;
}
System.out.println(new Inner2().num2);
}
}
访问成员内部类的成员:
1、内部类没有被static修饰:
外部类名.内部类名 对象名 = 外部类对象.内部类对象
例如:
Outer.Inner oi = new Outer().new Inner();
oi.method();
2、内部类被static修饰:
外部类名.内部类名 对象名 = new 外部类名.内部类名()
例如:
Outer.Inner inner = new Outer.Inner();
inner.method();
3、内部类被static修饰,内部类中成员也被static修饰:
外部类名.内部类名.成员
例:
Outer.Inner.method();
访问局部内部类的成员:
创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
参照上述代码中Out类中的method()。
注意:局部内部类访问局部变量必须用final修饰。
例如,将Out类中的method()改为如下:
public void method() {
final int numTest = 100;
class Inner2 {
int num2 = 2;
public void method() {
System.out.println(numTest);
}
}
在Inner2 中需要访问局部变量numTest,则必须将numTest定义为final类型。
原因:局部变量是随着方法的调用而调用,随着调用完毕而消失。而堆内存的内容并不会立即消失(类加载到堆内存中)。加入final修饰后,这个变量就成了常量,方法调用完成之后不会立即消失。
四、匿名内部类
匿名内部类就是没有名字的内部类,它是内部类的简化写法。匿名内部类只能使用一次,通常用来简化代码编写。
使用前提:必须继承一个父类(具体类或者抽象类)或者实现一个接口。
匿名内部类实质上是一个继承了父类或者实现了某个接口的子类匿名对象。
public class InterfaceTest {
public static void main(String[] args) {
//继承抽象类的匿名内部类
Person person = new Person() {
@Override
public void method() {
// TODO Auto-generated method stub
System.out.println("method()");
}
};
person.method();
//实现接口的匿名内部类
PersonStudy pStudy = new PersonStudy() {
@Override
public void study() {
// TODO Auto-generated method stub
System.out.println("study");
}
};
pStudy.study();
}
}
abstract class Person {
public abstract void method();
}
interface PersonStudy {
public abstract void study();
}