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 }

时间: 2024-08-05 07:06:41

java匿名对象的相关文章

java匿名对象_面向对象

class Student{ public void tell(){ System.out.println("Hello jikexueyuan"); } public void main{ Student stu=new Student(); stu.tell(); //匿名对象可以直接new 但是只能使用一次 new Student.tell(); } }

JAVA 匿名对象

/* 匿名对象: 没有名字的对象 匿名对象的使用方式之一: 当对对象方法只调用一次时,我们可以用匿名对象来完成,比较简化. 匿名对象的使用方式之二: 匿名对象可以被当做实参传递 */ class Car{ String color; void start(){ System.out.println("汽车被开动"); } } public class Test{ public static void main(String[] args){ //有名对象调用 Car a = new C

java 匿名对象,内部类,修饰符,代码块

匿名对象是在建对象时只有创建对象的语句方法而没有把对象的地址赋值给变量,匿名对象只能调用一次方法,想再调用时需要再创建一个新的匿名对象 创建普通对象:Person p =new Person(); 创建匿名对象:new Person().方法名(); new Person().setName("王无"); 内部类:写在其他类的内部或者成员位置或局部位置,这是其他类叫外部类.在内部类中可以访问外部类的属性. 当内部类写在成员位置时,叫成员内部类,写在局部位置时,叫局部内部类. 成员内部类

java匿名类和匿名对象及this的其他用法

/* 匿名内部类:就是内部类的简写格式. 必须前提:内部类必须继承或者实现一个类或者接口. 匿名内部类其实就是一个匿名 子类对象. 格式:new 父类对象 or 接口(){ 子类内容:(覆盖父类的, 而且可以增加自己的方法) }//相当于将 继承父类 和 new 的过程 写到了一起有某有!很方便有某有! */ class Outer{ int num; public Outer(){ num = 5; } class Inner{ int num; public Inner(){ num = 1

JAVA之旅(四)——面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块

JAVA之旅(四)--面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块 加油吧,节奏得快点了 1.概述 上篇幅也是讲了这点,这篇幅就着重的讲一下思想和案例 就拿买电脑来说吧,首先,你不懂电脑,你去电脑城买电脑,和大象装冰箱里一样,是什么步骤?咨询 砍价 ,谈妥了就那电脑走人,对吧,这就是面向过程的思想,而面向对象是:你有一个哥们,他懂电脑,什么都会,你只要带他去,就行,你这个哥们就是对象,在JAVA中,我们就是操作一个对象去完成各种各样的操作的,这就是面向对

JAVA笔记2__类/封闭性/构造方法/方法的重载/匿名对象

public class Main { public static void main(String[] args) { Chicken c1 = new Chicken(); Chicken c2 = null; c1.eat(); System.out.println(c1.age); c2 = c1; c2.eat(); } } class Chicken{ int color; char sex; int age; void eat(){ System.out.println("chik

Java基础学习笔记十 Java基础语法之final、static、匿名对象、内部类

final关键字 继承的出现提高了代码的复用性,并方便开发.但随之也有问题,有些类在描述完之后,不想被继承,或者有些类中的部分方法功能是固定的,不想让子类重写.可是当子类继承了这些特殊类之后,就可以对其中的方法进行重写,那怎么解决呢?要解决上述的这些问题,需要使用到一个关键字final,final的意思为最终,不可变.final是个修饰符,它可以用来修饰类,类的成员,以及局部变量. final的特点 final修饰类不可以被继承,但是可以继承其他类. class Yy {} final clas

C++不能显式调用构造函数,会生成匿名对象,这点与Java完全不一样!

Java有super(),但是C++里面没有.看一下这段代码: class A { public: A() { printf("A() \n"); } A(int d) { printf("A(int) \n"); A(); }  // 不能这样调用构造函数!会生成另一个匿名对象 ~A() { printf(" ~A \n"); } void ddd() { printf(" ddd \n"); } }; int main(i

java学习--基础知识进阶第二天--继承、匿名对象&amp;final、抽象类

今日内容介绍 u 继承 u 抽象类 第1章 继承 1.1 继承的概述 在现实生活中,继承一般指的是子女继承父辈的财产.在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系. 1.2 继承的格式&使用  在程序中,如果想声明一个类继承另一个类,需要使用extends关键字. 格式: class 子类 extends 父类 {} 1.2.1 案例代码一: package com.itheima_01; /* * 继承:多个类有共同的成员变量和成员方法,抽取到另外一个类