Java中的匿名内部类及内部类的二三事
匿名内部类适合创建那些只需要使用一次的类,它的语法有些奇怪,创建匿名内部类会立即创建一个该类的实例,这个类定义立即消失,且不能重复使用。
定义匿名类的格式如下:
new 实现接口() |父类构造器(实参列表){
//匿名内部类的类体部分
}
从定义来看,匿名内部类必须继承一个父类,或者实现一个接口,但是最多只能继承一个父类或者实现一个接口。
关于匿名内部类,还有如下两条规则:
- 匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。因此不允许将匿名内部类定义成抽象类。
- 匿名内部类不能定义构造器。因为匿名内部类没有类名,所以无法定义构造器。但是匿名内部类可以定义初始化块,通过实例初始化块来完成构造器需要完成的事情。
下面给出了一个常见的匿名内部类的使用示例:
public class Main {
public static void main(String[] args){
Main main = new Main();
main.test(new Man(){
//这里传入一个Man接口的匿名实现类的实例
public void talk(){
System.out.print("I'm a man!");
//output I'm a man!
}
});
}
public void test(Man m){
//调用该方法需要传入一个Man类型参数
m.talk();
}
}
interface Man{
void talk();
}
定义一个匿名内部类无需使用class关键字,而是在定义匿名内部类时直接生成该匿名内部类的对象。
由于匿名内部类不能是抽象类,所以匿名内部类必须实现它的抽象父类或者接口里包含的抽象方法。
虽然上面的例子完全可以采用使用实现类对象的方法来完成相同的功能,但是明显使用匿名内部类更加简洁。
当通过实现接口来创建匿名内部类时,匿名内部类不能显式创建构造器,因此匿名内部类只有一个隐式的无参数构造器,故new接口名后的括号中不能传入参数。
但是如果通过继承父类来创建匿名内部类时,匿名内部类将拥有和父类相似的构造器,注意此处相似的构造器指的是拥有相同形参列表。
下面是通过继承父类来创建匿名内部类的示例:
public class Main {
public static void main(String[] args){
Main main = new Main();
main.test(new Man("Amos H"){
//这里传入一个Man接口的匿名实现类的实例
public void talk(){
System.out.println(this.getName());
//output Amos H
}
public int getHight(){
return 175;
}
});
}
public void test(Man m){
//调用该方法需要传入一个Man类型参数
m.talk();
}
}
abstract class Man{
private String name;
public Man(String name){
this.name = name;
}
public void talk(){
System.out.println(name);
};
public String getName(){
return name;
}
public abstract int getHight();
}
可以看到,创造匿名内部类可以使用和父类相同的参数列表,调用父类的构造器。
当创建匿名内部类时,必须实现接口或者抽象父类中的所有抽象方法。如果有必要的话,可以重写父类中的普通方法。
内部类的二三事:
非静态内部类对象和外部类对象的关系如何?
非静态内部类对象必须寄生在外部类对象中,而外部类对象则不一定有非静态内部类对象寄生其中。因此外部类对象不能访问非静态内部类对象,而非静态内部类对象可以访问外部类成员,因为存在内部类必然存在外部类。
非静态内部类对象是否可以有静态初始化块?
非静态内部类对象不可以有静态初始化块,但是可以有普通初始化块。非静态内部类普通初始化块的作用与外部类初始化块的作用完全相同。
为何静态内部类的实例方法也不能访问外部类的实例属性?
因为静态内部类是外部类的类相关的,而不是外部类的对象相关的。静态内部类对象不是寄生在外部类的实例中,而是寄生在外部类的类本身中。当静态内部类对象存在时,并不一定存在一个被它寄生的外部类对象,静态内部类对象只持有外部类的类引用,并没有持有外部类对象的引用。如果允许静态内部类的实例方法访问外部类的实例成员,但找不到被寄生的外部类对象,这将引起错误。
如何实例化一个非静态内部类
非静态内部类的子类不一定是内部类,它也可以是一个外部类。但是非静态内部类的子类实例一样要保留一个引用,该引用用于指向其父类所在外部类的对象。也就是说,如果一个内部类子类的对象存在,则一定存在与之对应的外部类对象。因为要实例化一个非静态内部类的语法通常是这样的:
Out.In in = new Out().new In();
可以看到,非静态内部类的构造器必须使用外部类对象来调用。
Java中的匿名内部类及内部类的二三事的更多相关文章
- java中的几种内部类
Java中的几种内部类 内部类,听名字就可以知道是什么意思,就是类里面的类.有成员内部类,静态内部类,局部内部类和匿名内部类. 下面说一个每种内部类的的使用. 一. 成员内部类
- java中的匿名内部类总结(转)
源出处: java中的匿名内部类总结 匿名内部类也就是没有名字的内部类 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写 但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接 ...
- java中的匿名内部类
匿名内部类在java编码中不是很常见,它可一让类实现多继承的特性(多个父类~1个子类) java中的匿名内部类总结http://www.cnblogs.com/nerxious/archive/201 ...
- Java中使用google.zxing快捷生成二维码(附工具类源码)
移动互联网时代,基于手机端的各种活动扫码和收付款码层出不穷:那我们如何在Java中生成自己想要的二维码呢?下面就来讲讲在Java开发中使用 google.zxing 生成二维码. 一般情况下,Java ...
- java中的四种内部类使用(1)
内部类 (一) 概述 把类定义在另一个类的内部,该类就被称为内部类. 举例:把类Inner定义在类Outer中,类Inner就被称为内部类. class Outer { class Inner { } ...
- Java中的集合框架-Collection(二)
上一篇<Java中的集合框架-Collection(一)>把Java集合框架中的Collection与List及其常用实现类的功能大致记录了一下,本篇接着记录Collection的另一个子 ...
- java中注解的使用与实例 (二)
java 注解,从名字上看是注释,解释.但功能却不仅仅是注释那么简单.注解(Annotation) 为我们在代码中添加信息提供了一种形式化的方法,是我们可以在稍后 某个时刻方便地使用这些数据(通过 解 ...
- java中常用的工具类(二)
下面继续分享java中常用的一些工具类,希望给大家带来帮助! 1.FtpUtil Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...
- 走进Java中的持有对象(容器类)【二】Collection
概述 通过前文的学习,我们对容器的分类及常用容器类的作用有了基本的认识.本文将针对Collection容器的功能与使用进行细致分析. 基本操作 Collection集合抽象出的目的是为存放独立元素的序 ...
随机推荐
- html5 css选择器。 井号,句号的区别
.理解CSS的样式组成CSS里的样式表是有规则组成的,每条规则有三个部分组成:1.选择器(如下面例子中的:“body”),告诉浏览器文档的哪个部分受规则影响:2.属性(如实例中的font-family ...
- 卷积神经网络中的channel 和filter
在深度学习的算法学习中,都会提到 channels 这个概念.在一般的深度学习框架的 conv2d 中,如 tensorflow .mxnet,channels 都是必填的一个参数. channels ...
- 【.NET Core项目实战-统一认证平台】第五章 网关篇-自定义缓存Redis
[.NET Core项目实战-统一认证平台]开篇及目录索引 上篇文章我们介绍了2种网关配置信息更新的方法和扩展Mysql存储,本篇我们将介绍如何使用Redis来实现网关的所有缓存功能,用到的文档及源码 ...
- VSCode插件开发全攻略(十)打包、发布、升级
更多文章请戳VSCode插件开发全攻略系列目录导航. 发布方式 插件开发完了,如何发布出去分享给他人呢?主要有3种方法: 方法一:直接把文件夹发给别人,让别人找到vscode的插件存放目录并放进去,然 ...
- 【npm】伙计,给我来一杯package.json!不加糖
前言:夜深了,我熬了一锅热气腾腾的package.json,给大家端上来,希望大家喜欢 json和JS对象的区别 package.json,顾名思义,它是一个json文件,而不能写入JS对象. 所以我 ...
- 「总结」 MLEAutoMaton的各种板子总结
太菜了,所以咕了,欢迎评论留言... 网络流(不全) 自适应Simpson
- 折腾nock给jsonp进行单元测试
概述 前几天学习用Jest和nock.js对异步api进行单元测试.在项目中,我用到了jsonp,自然想到对jsonp进行单元测试. 过程很折腾,结果很有趣. jsonp.js 首先axios或者fe ...
- 随手用python写一个下载jdk源码爬虫
最近在研读jdk源码,网上找了下资源,发现都不完整. 后来新发现了一个有完整源码的地方,主要包括了java,c,c++的东西,装逼需要,就想拿来玩玩.但是,找了好多种下载打开的方式,发现都不对.于是, ...
- SpringBoot集成Thymeleaf模板引擎
简单介绍 目前在JavaEE领域有几中比较常用的模板引擎,分别是Jsp.Velocity.Freemarker.Thymeleaf,对Freemark语法不是特别熟悉,不过对于前端页面渲染效率来说,j ...
- vue 自学笔记记录
vue 自学笔记(一): 知识内容: 安装vue ,创建vue实例,安装第一个组件,单项数据流 https://www.cnblogs.com/baili-luoyun/p/10763163.htm ...