Java内部类(成员、静态、局部、匿名)
所谓内部类,就是在一个类里面再定义一个类,这个类就是内部类
成员内部类
-
成员内部类就是外部类的一个成员
-
我们先定义一个类(外部类)Outer,里面定义了一个成员内部类Inner
-
内部类Inner的实例化需要借助外部类Outer
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
public class Outer {
private int id=10;
private void out() {
System.out.println("这是外部类的方法");
}
public class Inner {
public void in() {
System.out.println("这是内部类的方法");
}
//内部类获得外部类的私有属性
public void getID() {
System.out.println(id);
}
//内部类获得外部类的私有方法
public void getOUT(){
out();
}
}
public static void main(String[] args) {
Outer outer = new Outer();
//通过这个外部类来实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getID();
inner.getOUT();
}
}
运行结果
这是内部类的方法
10
这是外部类的方法
可以看到内部类的一个显著优势:可以访问外部类的私有属性和方法
静态内部类
-
静态内部类就是使用static关键字修饰内部类
-
静态内部类可以直接实例化,不需要借助外部类了
Inner inner = new Inner();
public class Outer {
private static int id = 10;
private static void out() {
System.out.println("这是外部类的方法");
}
public static class Inner {
public void in() {
System.out.println("这是内部类的方法");
}
public void getID() {
System.out.println(id);
}
public void getOUT() {
out();
}
}
public static void main(String[] args) {
Inner inner = new Inner();
inner.in();
inner.getID();
inner.getOUT();
}
}
运行结果
这是内部类的方法
10
这是外部类的方法
需要注意的是:
- 静态内部类只能访问外部类的静态成员,非静态成员是访问不了的。比如静态内部类Inner的getID()方法只能访问外部类的静态属性id,如果id前不加static修饰,那么getID()是访问不了id的。很好理解:静态内容是最先加载的,齐次才是非静态内容,因此静态内容是访问不了非静态内容的。
- 使用静态内部类有很大的限制,一旦内部类加了static修饰成为静态内部类,那么它的所有方法只能访问外部类的静态成员,无法访问外部类的非静态成员,而我们又不能在一个非静态内部类里面定义静态方法或属性,这就给了静态内部类的成员引用造成了很大限制。
局部内部类
局部内部类就是在一个方法中定义类,就和局部变量一样
public class Outer1 {
public void method() {
//局部内部类
class Inner {
public void in() {
System.out.println("这是局部内部类");
}
}
//创建局部内部类的对象
Inner inner = new Inner();
//调用内部类方法
inner.in();
}
public static void main(String[] args) {
Outer1 outer = new Outer1();
outer.method();
}
}
运行结果
这是局部内部类
匿名内部类
匿名内部类算是很常见的一种,就是形如 new Object().method() 的方式去使用一个类的方法。
public class Test {
public static void main(String[] args) {
//正常情况我们是这样调用eat()方法的:
Apple apple = new Apple();
apple.eat();
//当我们只需要使用一次eat()方法时,可以不用将Apple实例化到变量里
//这叫做匿名对象的使用
new Apple().eat();
}
}
class Apple {
public void eat() {
System.out.println("吃苹果");
}
}
运行结果
吃苹果
吃苹果
对于接口的实现,更显现出了匿名内部类的方便
使用匿名内部类前:
public class Test {
public static void main(String[] args) {
//如果我们使用接口的方法:1.就需要先实现接口 2.创建接口类的实例对象 3.通过对象调用方法
Test02 test = new Test02();
test.method();
}
}
interface Test01 {
public void method();
}
class Test02 implements Test01 {
@Override
public void method() {
System.out.println("实现了接口的方法");
}
}
运行结果
实现了接口的方法
使用匿名内部类:
public class Test {
public static void main(String[] args) {
//使用匿名内部类
new Test01() {
@Override
public void method() {
System.out.println("实现了接口的方法");
}
}.method();
}
}
interface Test01 {
public void method();
}
运行结果
实现了接口的方法