Java 内部类

Java内部类包括非静态内部类,局部内部类,匿名内部类,静态内部类四种。前三种非常类似,它们都叫内部类,它们持有对外部对象的引用,最后一种也称为嵌套类,它和外部类没有联系,它更像仅仅写在类内部的正常类。
内部类是一种完善Java单继承机制从而取代多继承机制的产物,通过内部类可以进行灵活的继承而不影响外部类。所以它实际上有很多限制,需要用特殊的语法来进行保证,尽管这些语法可能看起来非常奇怪和不自然。幸运的是,日常对于这些边缘语法使用的也非常少。

四种内部类

非静态内部类

由于内部类实际上比较相似,所以这边将会展开非静态内部类讨论,其他三种只讨论和它的区别。
非静态内部类的共同特性:

  • 可访问外部类的所有成员
  • 不可以包含static成员,猜测static从设计上是属于类的,因为与原有设计冲突而诞生的规则。

基本形式

public class Main {
    public static void main(String[] args) {
        A a = new A();
        A.B b = a.getB();
        b.run();
    }
}

class A {
    private int val = 10;
    public A() {
        System.out.println("A()");
    }
    public B getB() {
        return new B();
    }
    // 隐藏内部类细节
    class B {
        public B() {
            System.out.println("B()");
        }
        public void run() {
            // 可访问外围类的所有成员
            System.out.println("B run " + val);
        }
    }
}

上述是一种内部类最常见的形式,也体现了内部类的两个用途:

  1. 隐藏内部类细节,作为一种代码的组织形式
  2. 内部类可以访问外部类的所有成员。

持有外部类的引用

内部类之所以可以访问外部类的所有成员,是因为内部类实际上在内部保存了对外部对象的一个引用,这一点,编译器会帮我们完成。
于是,我们需要记得是,在外部类对象不存在之前,我们不可能新建内部类对象。

特殊语法.new和.this

初始化外部类之前必须初始化内部类。这一点,引申出一种内部类的初始化特殊语法:

A a = new A();
A.B b1 = a.new B();

另外,由于类的嵌套,外部类和内部类中的this必然会产生冲突,所以Java又提供了补充规则,在内部类想访问外部类的对象时,可以使用:

A.this.run()

匿名内部类

匿名内部类是另一种非常常用的类。

class C {
    protected int val;

    public void run() {
        System.out.println(val);
    }
}

public class Main {
    private static int b = 19;
    public static void main(String[] args) {
        final int a = 1;
        C c = new C() {
            // 实例初始化,相当于默认构造器
            {
                val = 10;
                // 访问外部局部变量要求必须是final
                System.out.println(a);
                // 可以访问外围类的所有成员
                System.out.println(b);
            }
        };
        c.run();
    }
}

上述代码,本质上是创建了一个继承自C的匿名类的对象。这也是匿名内部类的本质,它拥有非静态内部类的所有特性:

  • 它可以访问外围类的所有成员

特殊区别:

  • 访问外部局部变量,要求局部变量必须为final
  • 由于匿名类没有名字,它也就无法重载构造器,替代的语法是使用代码块进行实例初始化

局部内部类

局部内部类指在代码块,方法中声明的局部类。
相同:

  • 它可以访问外围类的所有成员

不同

  • 只在作用域范围内有效
  • 局部内部类和匿名内部类的唯一区别是,我需要这个内部类有名字,方便在局部复用

静态内部类(嵌套类)

嵌套类与上述内部类区别比较大,它其实可以看错独立于外部类的类,唯一的限制是它被组织在外部类中而已。所以:

  • 静态内部类和外部类没有联系,没有持有外部类引用
  • 静态内部类只可以访问外部类的静态成员
  • 静态内部类可以包含静态成员
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值