内部类
内部类,指的是一个类在另一个类的内部中定义。
根据类定义的位置,可以分为以下几种:
- 成员内部类(常规内部类)
- 局部内部类
- 匿名内部类
- 静态内部类
成员内部类(常规内部类)
成员内部类是直接定义在另一个类的内部,与类成员并列。
特点:
- 成员内部类可以访问外部类的所有成员,包括私有属性。
- 在成员内部类中要想访问外部类的成员,可以通过
外部类.this.外部类成员进行访问 - 成员内部类中的属性和方法不能是静态的
- 创建成员内部类的对象时,需要外部类的对象存在
- 含有内部类的类文件经过源码编译后,除了外部类的字节码,还会产生内部类的字节码,格式为
外部类$内部类.class
java
package innerclass;
public class Demo {
private String name = "这是正常类中的属性";
public void testDemo() {
System.out.println("这是正常类中的方法");
}
// 成员内部类
public class InnerDemo {
private String name = "这是成员内部类的属性";
public void testInnerDemo() {
System.out.println("这是成员内部类的方法: " + this.name);
Demo.this.testDemo();
System.out.println("在成员内部类中访问外部类的私有属性: " + Demo.this.name);
}
}
}java
package innerclass;
import innerclass.Demo.InnerDemo;
public class Test {
public static void main(String[] args) {
Demo d = new Demo();
// 创建成员内部类的对象时,需要外部类的对象存在
InnerDemo iD = d.new InnerDemo();
iD.testInnerDemo();
}
}局部内部类
局部内部类是在外部类的方法或程序块中定义的,与局部变量并列。
特点:
局部内部类相当于一个变量,具有临时性,因此不能用 public、protected、private 和 static 修饰
局部内部类只可以直接访问方法中被 final 修饰的变量
在不同的方法中定义同名的局部内部类时,它们的字节码格式为
外部类$1内部类.class、外部类$2内部类.class....
java
package innerclass;
public class Demo {
private String name = "这是正常类中的属性";
public void testDemo() {
System.out.println("这是正常类中的方法");
}
public void testDemoPart() {
// 局部内部类,临时性存在
class PartInnerDemo {
private String name = "这是局部内部类的属性";
public void testPartInnerDemo() {
System.out.println("这是局部内部类的方法: " + this.name);
}
}
PartInnerDemo pID = new PartInnerDemo();
pID.testPartInnerDemo();
}
public static void main(String[] args) {
Demo d = new Demo();
d.testDemoPart();
}
}匿名内部类
匿名内部类通常表现为接口或抽象类的具体子类。
特点:
- 匿名内部类只有类体,没有类的所有结构(修饰符、类名、继承、实现)
- 匿名内部类没有构造方法
常规的接口与子类实现如下:
java
public interface Animal {
void eat();
}
public class Dog implements Animal {
void eat() {
System.out.println("狗吃骨头");
}
}
public class Test {
public static void main(String[] args) {
Anima a = new Dog();
a.eat();
}
}而匿名内部类则省略了类名:
java
public interface Animal {
void eat();
}
public class Test {
public static void main(String[] args) {
Animal dog = new Animal(){
void eat() {
System.out.println("狗吃骨头");
}
};
dog.eat();
}
}静态内部类
静态内部类跟成员内部类相似,区别在于静态内部类多了一个 static 修饰符,因此在创建静态内部类对象时,不需要借助外部类的对象,可以直接创建。
特点:
- 静态内部类只能访问外部类的静态成员
java
package innerclass;
public class Demo {
private String name = "这是正常类中的属性";
public void testDemo() {
System.out.println("这是正常类中的方法");
}
public static class StaticInnerDemo {
private String name = "这是静态内部类的属性";
public void testStaticInnerDemo() {
System.out.println("这是静态内部类的方法: " + name);
}
}
public static void main(String[] args) {
Demo.StaticInnerDemo sID = new Demo.StaticInnerDemo();
sID.testStaticInnerDemo();
}
}