java 内部类 局部内部类 匿名内部类 成员内部类 静态内部类
发布日期:2021-05-07 10:30:28 浏览次数:18 分类:精选文章

本文共 7073 字,大约阅读时间需要 23 分钟。

Java 内部类详解

内部类概述

一个类可以完全包裹另一个类结构,被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。内部类的最大特点是可以直接访问私有属性,并且能体现类与类之间的包含关系。

// 外部类
class Outer {
// 内部类
class Inner {
}
}
// 其他类/外部其他类
class Other {
}

内部类分类

  • 定义在外部类局部位置上:
  • 局部内部类(有类名)
  • 匿名内部类(没有类名)
  • 定义在外部类成员位置上:
  • 成员内部类(没有static修饰)
  • 静态内部类(使用static修饰)

局部内部类

  • 局部内部类是定义在外部类的局部位置,通常在方法中,并且有类名。
  • 可以直接访问外部类的所有成员,包括私有的。
  • 不能添加访问修饰符,因为它的地位是局部变量,但可以使用final修饰,因为局部变量也可以使用final。
  • 作用域:仅在定义它的方法或代码块中。
public class LocalInnerClass {       
public static void main(String[] args) {
Outer02 outer02 = new Outer02();
outer02.m1();
}
}
class Outer02 {
private int n1 = 100;
private void m2() {
System.out.println("Outer02 m2()");
}
public void m1() {
class Inner02 {
private int n1 = 800;
public void f1() {
System.out.println("n1= " + n1 + " 外部类的n1=" + Outer02.this.n1);
m2();
}
}
Inner02 inner02 = new Inner02();
inner02.f1();
}
}

匿名内部类

  • 本质上是类,但没有名字。
  • 内部类。
  • 匿名内部类是定义在外部类的局部位置,并且没有类名。
public class Anonymous {       
public static void main(String[] args) {
new Outer04().method();
}
}
class Outer04 {
private int n1 = 10;
public void method() {
// 基于接口的匿名内部类
// 传统方式: 写一个类,实现该接口,并创建对象
// 使用匿名内部类来简化开发
IA tiger = new IA() {
@Override
public void cry() {
System.out.println("老虎叫唤");
}
};
System.out.println("tiger的运行类型: " + tiger.getClass());
tiger.cry();
// 基于类的匿名内部类
Father father = new Father("jack") {
@Override
public void test() {
System.out.println("匿名内部类重写了test方法");
}
};
System.out.println("father的运行类型: " + father.getClass());
father.test();
// 基于抽象类的匿名内部类
Animal animal = new Animal() {
@Override
void eat() {
System.out.println("吃东西");
}
};
System.out.println("animal的运行类型: " + animal.getClass());
animal.eat();
}
}

细节

public class AnonymousInnerClassDetail {       
public static void main(String[] args) {
Outer05 outer05 = new Outer05();
outer05.f1();
System.out.println(outer05.hashCode());
}
}
class Outer05 {
private int n1 = 99;
public void f1() {
// 创建一个基于类的匿名内部类
// 不能添加访问修饰符,因为它的地位是局部变量
// 作用域: 仅仅在定义它的方法或代码块中
Person person = new Person() {
private int n1 = 23;
@Override
public void hi() {
System.out.println("匿名内部类重写了hi方法, n1:" + n1 + ", 访问外部类的n1:" + Outer05.this.n1);
System.out.println(Outer05.this.hashCode());
}
};
person.hi();
new Person() {
@Override
public void hi() {
System.out.println("哈哈哈");
}
@Override
public void ok(String str) {
System.out.println("ok" + str);
}
}.ok("123");
}
}

成员内部类

  • 成员内部类是定义在外部类的成员位置,并且没有static修饰。
  • 可以直接访问外部类的所有成员,包括私有的。
  • 可以添加任意访问修饰符(public, protected, 默认, private),因为它的地址是外部类的成员。
public class MemberInnerClass01 {       
public static void main(String[] args) {
Outer.Inner08 inner08 = new Outer().new Inner08();
inner08.say();
new Outer().test();
}
}
class Outer {
private int n1 = 10;
public String name = "张三";
class Inner08 {
public void say() {
System.out.println(n1 + "," + name);
}
}
public void test() {
Inner08 inner08 = new Inner08();
inner08.say();
}

成员内部类练习

public class Homework07 {       
public static void main(String[] args) {
Car car = new Car(-1);
car.getAir().flow();
new Car(60).new Air().flow();
}
}
class Car {
private double temperature;
public Car(double temperature) {
this.temperature = temperature;
}
class Air {
public void flow() {
if (temperature > 40) {
System.out.println("冷气");
} else if (temperature < 0) {
System.out.println("暖气");
} else {
System.out.println("关闭空调");
}
}
}
public Air getAir() {
return new Air();
}

静态内部类

  • 静态内部类是定义在外部类的成员位置,并且有static修饰。
  • 可以直接访问外部类的所有静态成员,包括私有的,但不能访问非静态成员。
  • 可以添加任意访问修饰符(public, protected, 默认, private),因为它的地位是外部类的成员。
  • 作用域:同其它成员一样。
public class StaticInnerClass01 {       
public static void main(String[] args) {
Outer10.Inner10 inner10 = new Outer10.Inner10();
inner10.test();
}
}
class Outer10 {
private int n1 = 10;
private static String name = "张三";
static class Inner10 {
public void test() {
System.out.println(name);
}
}
上一篇:java 实现接口 vs 继承类
下一篇:java 接口(Interface)多态特性

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2025年05月04日 08时48分19秒