java匿名对象
java学习面向对象之匿名内部类
之前我们提到“匿名”这个字眼的时候,是在学习new对象的时候,创建匿名对象的时候用到的,之所以说是匿名,是因为直接创建对象,而没有把这个对象赋值给某个值,才称之为匿名。
匿名对象回顾:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
class NoObject { void method() { System.out.println( "Hello NoNameObj" ); } } class NoName { public static void main(String[] args) { new NoObject().method(); // 这里创建完对象之后,并没有把对象直接赋值给某个值,而是创建完对象之后,直接调用对象,之后这个对象就不能被其他对象调用了<br> //因为要调用一个对象必须知道他的名字吧,没有名字怎么调用,这个就是匿名的概念。完事之后就成垃圾了不能再 调用了。 } } |
因为在使用匿名对象的时候,那个对象只需要调用一次就好了,为了简写我门采用了匿名的写法。那么这里的匿名内部类也不例外,这里的匿名内部类也是内部类的一个简写,因为只需要调用一次就好了。那我们来看下日常内部类都是怎么调用的。
1 class Outer
2 {
3
4 int num = 10;
5
6 class Inner
7 {
8
9 void method()
10 {
11
12 System.out.println("The Outer Num is "+num);
13
14 }
15
16 }
17
18 void sayInner()
19 {
20
21 new Inner().method();
22
23 }
24
25 }
26
27
28 class InnerClassDemo2
29 {
30
31 public static void main(String[] args) {
32
33 new Outer().sayInner();
34
35 }
36
37 }
我们正常调用内部类是这个样子调用的,如果是匿名内部类又是怎样的呢,我们按照匿名对象的思维来思考一下:
匿名对象没有把创建的值赋给指定类型的引用变量,还有就是这个对象用一次之后就不能用第二次了。相应的:
匿名类,第一个就是没有类名,第二个就是这个类用完一次之后,不能被实例化第二次,也就是匿名应用的时候采用,但是这个类不是真实存在的。
但是这里就存在一个问题了,一个类没有名字我们如何去实例化这个类?所以说要使用匿名内部类是有条件的:
使用匿名对象的条件:
内部类必须继承或者实现一个外部类接口,满足这个条件我们才能使用内部类。代码示例:
1 abstract class AbsDemo
2 {
3
4 abstract void demo();
5
6 }
7
8 class Outer
9 {
10
11 int num = 10;
12
13
14 void sayInner()
15 {
16 /**
17 *这个地方我们直接new了一个父类或者接口类,但是这里有一点需要注意,那就是在new完了父类或者实现的接口之后,
18 *后面要加上大括号,加上大括号的意义是在于表示,这是一个类,并且是new关键字后面的类或者接口的子类或者实现
19 *之后我们在大括号后直接覆盖或者实现了类或者接口的方法
20 */
21 new AbsDemo()
22 {
23
24 void demo()
25 {
26
27 System.out.println("This is a NoNameInnerClass Demo");
28
29 }
30
31 }.demo();//这个地方是非常容易出错的,往往我们new abs(){}之后就忘了调用,因为我们只是单纯的new abs(){}这个样子是没有
32 //任何意义的,为什么因为这个是个匿名的类,也就是说没有类名,你匿名定义之后完了,就不能再引用了。只能立即调用
33 //这个方法后才会变的有意义。还有一点就是这个匿名类定义调用完之后,不要忘了后面的分号结束语句,因为new之后就是
34 //一个语句了,而不是class声明了。
35
36 }
37
38 }
39
40
41 class InnerClassDemo2
42 {
43
44 public static void main(String[] args) {
45
46 new Outer().sayInner();
47
48 }
49
50 }
匿名内部类通俗来说就是:就是一个匿名子类对象。定义的方法是:new 父类or接口(){子类内容}
匿名内部类的应用:
场景一:当函数参数是接口类型时,且接口方法不超过3个,此时我们可以采用匿名内部类来当参数传递。比如:
1 interface InterfaceDemo
2 {
3
4 public void show1();
5 public void show2();
6
7 }
8
9 class InnerClassDemo2
10 {
11
12 public static void main(String[] args) {
13
14 method(new InterfaceDemo(){
15
16 public void show1()
17 {
18
19 System.out.println("Show 1");
20
21 }
22
23 public void show2()
24 {
25
26 System.out.println("Show 2");
27
28 }
29
30 });
31
32 }
33
34 static void method(InterfaceDemo demo)
35 {
36
37 demo.show1();
38 demo.show2();
39 }
40
41 }
这里method()方法需要一个接口类型的对象传入,为了简便期间,我们直接用了匿名内部类对象进行了传递,这样是不是很方便呢?但是这里还有一个地方需要注意,就是假如有现在这样的情况:
1 class InnerClassDemo2
2 {
3
4 class Inner
5 {
6
7
8 }
9
10 public static void main(String[] args) {
11
12 new Inner();
13
14 }
15
16
17 }
如果我们此时这么运行的话就会报下面的错误:
InnerClassDemo2.java:21: 错误: 无法从静态上下文中引用非静态 变量 this
new Inner();
^
1 个错误
为什么呢?因为我们知道main函数是静态的,他无法调用静态上下文当中的非静态成员,此时class Inner{}在这个类当中就相当于一个成员,但是是非静态的自然而然会报错的。
在这里还有一个多态的问题需要我们注意:比如
1 interface InterfaceDemo
2 {
3
4 public void show1();
5 public void show2();
6
7 }
8
9 class DuoTaiFalse
10 {
11
12 void method()
13 {
14
15 /**
16 *这个地方发生了向上转型。即多态
17 */
18 InterfaceDemo inface = new InterfaceDemo(){
19
20 public void show1()
21 {
22
23 System.out.println("Show1");
24
25 }
26 public void show2()
27 {
28
29 System.out.println("Show2");
30
31 }
32
33 public void show3()
34 {
35
36 System.out.println("Show3");
37
38 }
39
40 };
41
42 inface.show1();
43 inface.show2();
44 /**这个地方就是错误的,因为InterfaceDemo inface = new InterfaceDemo(){}当进行到这个地方的时候,就已经发生了
45 *向上转型,也就是说这个时候,不能够调用除父类当中已经有的其他的方法。所以调用inface.show3()会提示错误
46 */
47 //inface.show3();
48
49 }
50
51
52 }
53
54 class InnerClassDemo2
55 {
56
57 public static void main(String[] args) {
58
59 new DuoTaiFalse().method();
60
61 }
62
63 }
java匿名对象的更多相关文章
- Java匿名对象介绍
Java匿名对象介绍 什么是匿名对象? 顾名思义就是没有变量名的对象,即创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量. 匿名对象命名格式:以Scanner类举例 new Scann ...
- 10. java 匿名对象说明
一.匿名对象 public class Demo{ public static void main(String[] args){ Person one = new Person(); one.nam ...
- Java匿名对象导致的内存泄漏
这几天与在某群与群友讨论了Runnable匿名对象导致内存泄漏的相关问题,特此记录一下. 示例代码如下: package com.memleak.memleakdemo; public class L ...
- java匿名对象_面向对象
class Student{ public void tell(){ System.out.println("Hello jikexueyuan"); } public void ...
- JAVA 匿名对象
/* 匿名对象: 没有名字的对象 匿名对象的使用方式之一: 当对对象方法只调用一次时,我们可以用匿名对象来完成,比较简化. 匿名对象的使用方式之二: 匿名对象可以被当做实参传递 */ class Ca ...
- java 匿名对象,内部类,修饰符,代码块
匿名对象是在建对象时只有创建对象的语句方法而没有把对象的地址赋值给变量,匿名对象只能调用一次方法,想再调用时需要再创建一个新的匿名对象 创建普通对象:Person p =new Person(); 创 ...
- Java匿名对象和匿名类总结
一.匿名对象 匿名对象是没有名字的实体,也就是该实体没有对应的变量名引用 匿名对象的特征: 创建的匿名类的对象只能够调用一次 匿名对象只在堆内存中开辟空间 ...
- [转载]java匿名对象
来源:https://blog.csdn.net/qiaoquan3/article/details/53300248 匿名对象:没有名字的对象:new Car(); //匿名对象其实就是定义对象的 ...
- Java 匿名对象、内部类
一.匿名对象 1.概念 匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量. public class Person{ public void eat(){ System.o ...
随机推荐
- mysql 连接语句
在 SELECT 语句中,如果 FROM 子句引用了多个表源或视图,可以使用 JOIN 指示指定的联接操作应在指定的表源或视图之间执行. 一.交叉联接:CROSS JOIN 交叉联接将执行一个叉积(迪 ...
- Entity Framework(一) 映射
ADO.NET Entity Framework通过Modeel First和DataBase First,提供了几个把数据库表映射到对象上的曾.通过Database First,可以从一个数据库架构 ...
- 多路选择器(multiplexer)简介
1.多路器简介 简称:多路器 功能:多输入 单输出 组合逻辑电路 2.verilog代码实现: module Mux_8(addr,in1,in2,in3,in4,in5,in6,in7,in8 ...
- android实现可拖动按钮
功能:在Android中实现可拖动按钮,同时实现按钮的点击功能 相关问题: 按钮拖动的界限限定. 按钮单击和拖动之间的冲突. 在界面未显示之前,获得View的高/宽. 问题描述: 如果不为按钮的拖动范 ...
- iOS常见问题(5)
一.注意将之前storyboard中控制器删除之后,拖入一个新的控制器的时候,stroyboard中控制器的class也要重新填入自己想要展示的控制器,告诉stroyboard去加载哪个控制器. 二. ...
- WebAPi性能
提高WebAPi性能 前言 WebAPi作为接口请求的一种服务,当我们请求该服务时我们目标是需要快速获取该服务的数据响应,这种情况在大型项目中尤为常见,此时迫切需要提高WebAPi的响应机制,当然 ...
- Interview-Harry Potter walk through matrix.
假设你是harry potter,在grid的左上角,你现在要走到右下角,grid中有正数也有负数,遇到正数表示你的strength增加那么多,遇到负数表示strength减少那么多,在任何时刻如果你 ...
- 【软件工程-Teamwork 2】必应词典软件手机版测试报告
测试人员:聂健(N).居玉皓(J).吴渊渊(Wy).汪仁贵(Wr).吕佳辉(L).杜冰磊(D) 测试软件:必应词典软件手机版 版本:2.2.0版本(Android) 引言: 我们的测评报告的主体主要分 ...
- linux 命令小结
chkconfig --list 查询所有服务运行情况 修改文件夹权限: 在Linux中,权限的所有者分为用户权限,组权限和其他权限,分别是用字母u, g, o 代表权限分为:读 r , 写 w , ...
- 输入adb shell 时 提示error: more than one device and emulator
第一种情况:确实用多个设备或者模拟器 解决办法:(指定连接某一个设备或者模拟器) 1.获取模拟器/设备列表 adb devices 2.指定device来执行adb shell adb -s ...