【Java入门提高篇】Day7 Java内部类——局部内部类

  今天介绍第二种内部类——局部内部类。

  局部内部类是什么?顾名思义,那就是定义在局部内部的类(逃)。开玩笑的,局部内部类就是定义在代码块、方法体内、作用域(使用花括号“{}”括起来的一段代码)内的类。局部内部类有以下特性:

  1. 局部内部类只能在代码代码块、方法体内和作用域中使用。
  2. 局部内部类同样可以无限制调用外部类的方法和属性。
  3. 可以使用abstract修饰,声明为抽象类。

  举个栗子:

public class Outer2 {
    public void print(){
        class Inner2{
            public void test(){
                System.out.println("Inner.print()");
            }
        }
        Inner2 inner2 = new Inner2();
        inner2.test();
    }
}
public class Test {
    public static void main(String[] args) {
        Outer2 outer2 = new Outer2();
        outer2.print();
    }
}

  这里的Inner2类仅仅在Outer2的print方法中被使用,有效范围也仅在print函数之内。

  通过这段玩具代码,可能无法理解为什么java中要出现这样限制这么多而且挺复杂的东西。让我们来看看之前的栗子:Java中的回调

  这里把代码复制过来:

public class TimePrinter implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        Date now = new Date();
        System.out.println("Time is " + now + " now.");
    }
}
public class Test {
    public static void main(String[] args) {
        ActionListener listener = new TimePrinter();
        Timer t = new Timer(1000,listener);
        t.start();
        JOptionPane.showMessageDialog(null,"Quit program?");//弹出对话框,防止主线程结束导致时钟结束
        System.exit(0);
    }
}

  在这里,我们想要创建一个Timer时,需要往里面传入一个实现了ActionListener接口的对象,而这个对象仅仅在该方法中使用了一次,这时候内部类的优势就体现出来了,把类封装在方法中,不向外界提供任何冗余信息:

public class Test {
    public static void main(String[] args) {
        class InnerTimePrinter implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                Date now = new Date();
                System.out.println("Time is " + now + " now.");
            }
        }
        ActionListener listener = new InnerTimePrinter();
        Timer t = new Timer(1000,listener);
        t.start();
        JOptionPane.showMessageDialog(null,"Quit?");
        System.exit(0);
    }
}

  你也许会觉得,这样好像只是把类简单的挪到了另一个类里面,并没有什么luan用。

  表面上,确实如此,但事实上,还是有很多luan用的。

  在《Think in java》中有这样一句话:使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

  我们都知道,java中是不能实现多继承的,接口也正是为了对多继承的补充完善给出的方案。而我们程序设计中有时候会存在一些使用接口很难解决的问题,这个时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问题。可以说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。

  据个人经验,局部内部类确实用的不多,但不常用不代表没有用,知道有这样一个神奇的内部类存在,了解过它的特性之后,可以为你日后的需求提供更多的方案。

  至此,本篇讲解完毕,欢迎大家继续关注!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我的技术专栏

C++编译期多态与运行期多态

14440
来自专栏轮子工厂

8. 一花一世界,while for 循环?

wo这周有点懒啊,这才第 2 篇,个人有点事情,本来预计可以更新……1 篇的,︿( ̄︶ ̄)︿

12020
来自专栏猿人谷

怎样写解释器

解释器是比较深入的内容。虽然我试图从最基本的原理讲起,尽量让这篇文章不依赖于其它的知识,但是这篇教程并不是针对函数式编程的入门,所以我假设你已经学会了最基本的 ...

22270
来自专栏闰土大叔

闰土说JS进阶之变量

前言 前端世界如此喧嚣,能进阶的何其稀少。大家好,你们的闰土哥在沉寂了数月之后又回来了!(此处应有掌声~~~) 前段时间在群里关于“闰土去哪儿了”的话题,让我既...

371100
来自专栏Java帮帮-微信公众号-技术文章全总结

【Java提高十二】hashCode()equals()

hashCode的作用 要想了解一个方法的内在原理,我们首先需要明白它是干什么的,也就是这个方法的作用。在讲解数组时,我们提到数组是java中效率最高的数据结...

27640
来自专栏微信公众号:Java团长

JAVA之旅(一)——基本常识,JAVA概念,开发工具,关键字/标识符,变量/常量,进制/进制转换,运算符,三元运算

比如6:6/2 = 3 余 0 3 / 2 = 1 余 1 那就是从个位数开始011,读起来就是110了

18710
来自专栏java学习

每日一练(2017/5/18)

Java基础 | 数据库 | Android | 学习视频 | 学习资料下载 课前导读 ●回复"每日一练"获取以前的题目! ●答案公布时间:为每期发布题目的第二...

26450
来自专栏java架构师

Stream篇(2)【TextReader】

说明:一个对于Text的读取器。无论哪种文件类型,其实都是通过一个个char组成的。 这是个抽象类,无法直接实例化 重要方法: 1、void Close() 2...

35390
来自专栏阮一峰的网络日志

Javascript 面向对象编程(一):封装

学习Javascript,最难的地方是什么? 我觉得,Object(对象)最难。因为Javascript的Object模型很独特,和其他语言都不一样,初学者不容...

38170
来自专栏分布式系统和大数据处理

四种简单的排序算法

我觉得如果想成为一名优秀的开发者,不仅要积极学习时下流行的新技术,比如WCF、Asp.Net MVC、AJAX等,熟练应用一些已经比较成熟的技术,比如Asp.N...

14520

扫码关注云+社区

领取腾讯云代金券