`
tntxia
  • 浏览: 1484751 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

关于Java的内部匿名类的讨论

阅读更多

关于JAVA内部类:一个内部类的定义是定义在另一个类内部的类。
  存在它的原因是:
  1.一个内部类的对象能够访问创建它的对象的实现,包括私有数据。即内部类实例对包含它的哪个类的实例来说,是特权的。
  2.对于同一个包中的其他类来说,内部类能够隐藏起来,换句话说,内部类不管方法的可见性如何,那怕是public,除了包容类,其他类都无法使用它。
  3.匿名内部类可以很方便的定义回调。
  4.使用内部类可以非常方便的编写事件驱动程序。

其实它真正的目的仅仅为了定义回调--进一步就是事件驱动。
接口和回调:编程一个常用的模式是回调模式,在这种模式中你可以指定当一个特定时间发生时回调对象上的方法。
-----------------------------------------------
   
注意事项:

匿名类和内部类中的中的this :
有时候,我们会用到一些内部类和匿名类。当在匿名类中用this时,这个this则指的是匿名类或内部类本身。
这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。如下面这个例子:

public class A {
   int i = 1;
   public A() {
     Thread thread = new Thread() {
       public void run() {
         for(;;) {
           A.this.run();
           try {
             sleep(1000);
           } catch(InterruptedException ie) {
           }
         }
       }
     };
     thread.start();
   }
   public void run() {
     System.out.println("i = " + i);
     i++;
   }
   public static void main(String[] args) throws Exception {
     new A();
   }
}


    
在上面这个例子中, thread 是一个匿名类对象,在它的定义中,它的 run 函数里用到了外部类的 run 函数。
    
这时由于函数同名,直接调用就不行了。这时有两种办法,一种就是把外部的 run 函数换一个名字,但这种办法对于一个开发到中途的应用来说是不可取的
    
。那么就可以用这个例子中的办法用外部类的类名加上 this 引用来说明要调用的是外部类的方法 run

对于这个例子:

this.test(new Inner(){
              public void method1(){
                  System.out.print("1111");
            }
           
              public void method2(){
                  System.out.print("22222");
            }
});
这个时候调用test()方法,那Inner类的method1method2是什么时候被调用的?难道也是this对象向他们发消息(比如传入一个参数)吗?还是直接显式的调用??

对于Inner类,除了this这个类,就是this.test(...那句中的this,它能够调用Inner类的方法,其他地方都不行,然而,这也需要你在类中有个地方保存有对这个内部类实例的引用才可以。再说明一次,内部类是用来在某个时刻调用外面的方法而存在的--这就是回调。
为了说明内部类实例的方法只能在包容类的实例中调用,其他地方无法调用,给个例子如下:
JAVA2
实用教程源码:

/**
一个应用程序,用来演示内部类的使用 */
/**
Outer */
class Outer{
private static int size;
/**
内部类Inner的声明 */
public class Inner{
private int size;
/**
方法doStuff() */
public void doStuff(int size){
size++; //
存取局部变量
this.size++;   //
存取其内部类的成员变量
Outer.this.size++; //
存取其外部类的成员变量
System.out.println(size+" "+this.size+" "+Outer.this.size);
}
}//
内部类Inner结束
/**
Outer中定义的实例方法testInner()方法 */
public void testInner(){
Inner i=new Inner();
i.doStuff(5);
}
/** main()
方法 */
public static void main(String[] a){
Outer o=new Outer();
o.testInner();
}
}//
Outer结束

那么,如何使用内部类,匿名类实现事件处理呢?
JAVA---
事件适配器

1
.事件适配器--EventAdapter
  下例中采用了鼠标适配器:
  

import java.awt.*;
  import java.awt.event.*;
  public class MouseClickHandler extends MouseAdaper{
    public void mouseClicked(MouseEvent e) //只实现需要的方法
       { ……}
  }

  java.awt.event包中定义的事件适配器类包括以下几个:
  1ComponentAdapter( 组件适配器)
  2ContainerAdapter( 容器适配器)
  3FocusAdapter( 焦点适配器)
  4KeyAdapter( 键盘适配器)
  5MouseAdapter( 鼠标适配器)
  6MouseMotionAdapter( 鼠标运动适配器)
  7WindowAdapter( 窗口适配器)
 2. 用内部类实现事件处理
  内部类(inner class)是被定义于另一个类中的类,使用内部类的主要原因是由于:
  一个内部类的对象可访问外部类的成员方法和变量,包括私有的成员。
  实现事件监听器时,采用内部类、匿名类编程非常容易实现其功能。
  编写事件驱动程序,内部类很方便。  
  因此内部类所能够应用的地方往往是在AWT的事件处理机制中。
5.11
   
import java.awt.* ;
   import java.awt.event.*
     public class InnerClass{
       private Frame f;
       private TextField tf;
       public InnerClass(){
       f=new Frame("Inner classes example");
       tf=new TextField(30);
     }
     public voidi launchFrame(){
       Label label=new Label("Click and drag the mouse");
       f.add(label,BorderLayout.NORTH);
       f.add(tf,BorderLayout.SOUTH);
       f.addMouseMotionListener(new MyMouseMotionListener());/*参数为内部类对象*/
       f.setSize(300,200);
       f.setVisible(true);
     }
     class MyMouseMotionListener extends MouseMotionAdapter{ /*内部类开始*/
       public void mouseDragged(MouseEvent e) {
         String s="Mouse dragging: x="+e.getX()+"Y="+e.getY();
         tf.setText(s); }
       } ;
       public static void main(String args[]) {
         InnerClass obj=new InnerClass();
         obj.launchFrame();
       }
     }//内部类结束
    }

3.匿名类(Anonymous Class
  当一个内部类的类声名只是在创建此类对象时用了一次,而且要产生的新类需继承于一个已有的父类或实现一个接口,才能考虑用匿名类,由于匿名类本身无名,因此它也就不存在构造方法,它需要显示地调用一个无参的父
类的构造方法,并且重写父类的方法。所谓的匿名就是该类连名字都没有,只是显示地调用一个无参的父类的构造方法。
5.12
   

import java.awt.* ;
   import java.awt.event.*;
    public class AnonymousClass{
     private Frame f;
     private TextField tf;
     public AnonymousClass(){
      f=new Frame("Inner classes example");
      tf=new TextField(30);
    }
    public void launchFrame(){
      Label label=new Label("Click and drag the mouse");
      f.add(label,BorderLayout.NORTH);
      f.add(tf,BorderLayout.SOUTH);
      f.addMouseMotionListener(new MouseMotionAdapter(){ //匿名类开始
       public void mouseDragged(MouseEvent e){
        String s="Mouse dragging: x="+e.getX()+"Y="+e.getY();
        tf.setText(s); }
      } ); //匿名类结束
      f.setSize(300,200);
      f.setVisible(true);
      }
       public static void main(String args[]) {
        AnonymousClass obj=new AnonymousClass();
        obj.launchFrame();
        }
      }

  其实仔细分析,例5.115.12实现的都是完全一样的功能,只不过采取的方式不同。5.11中的事件处理类是一个内部类,而5.12的事件处理类是匿名类,可以说从类的关系来说是越来越不清楚,但
是程序也越来越简练。熟悉这两种方式也十分有助于编写图形界面的程序。
亲自在IDE中实践一下,会理解的更深切一点。

分享到:
评论

相关推荐

    观看韩顺平学习整理java的笔记到异常

    匿名内部类的使用(重要!!!!!!!) 13 成员内部类的使用 13 静态内部类的使用 14 枚举的二种实现方式 14 自定义类实现枚举 14 使用 enum 关键字实现枚举注意事项 15 enum 用方法说明 15 enum 实现接口 15 注解的理解 16...

    java初学者必看

    10.5 匿名内部类 10.5.1 继承式 10.5.2 接口式 10.5.3 参数式 10.6 静态嵌套类 10.7 内部类的继承 10.8 本章习题 第11章 线程 11.1 线程基础 11.1.1 什么是线程 11.1.2 Thread创建线程 11.1.3 Thread创建...

    Java期末重点复习(1)

    免费哒!!!哈哈哈反正写都写了,...至于第二辑,暂定是想和大家讨论下接口类、匿名内部类和Lambda表达式、泛型、流和Collection。 嗯,然后几次复习的内容做完了,我就要着手开始做课设了,到时候更新会更慢......

    JAVA语言程序设计【高清版】.pdf

    90 5.7.2 接口的定义 91 5.7.3 接口的实现 91 5.8 Java包 94 5.8.1 Java包的概念 94 5.8.2 import语句 95 5.9 内部类 97 5.9.1 内部类的概念 97 5.9.2 匿名类 99 习题 100 第6章 数组、容器和字符...

    Java期末重点复习(2)

    ③匿名内部类和Lambda ④Collection 关于资源的内容,主要是我写的一些Demo,看了比较有眉目的那种,方便仿照着写的那种。 至于第三辑,暂定是想和大家讨论流、文件io、UI等等,感觉挺难的啊......不确定我多久可以...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【基础】Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口? 30 【基础】Java 中的final关键字有哪些用法? 31 【基础】内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制? 31 ...

    j2objc:从Java到iOS的Objective-C转换工具和运行时

    J2ObjC支持客户端应用程序开发人员所需的大多数Java语言和运行时功能,包括异常,内部和匿名类,泛型,线程和反射。 还支持JUnit测试转换和执行。 J2ObjC当前为beta质量。 几个Google项目都依赖它,但是当新项目...

    深入理解Android:卷I--详细书签版

     第5章讲解了Android源码中常用的类,如sp、wp、RefBase、Thread类、同步类、Java中的Handler类以及Looper类。这些类都是Android中最常用和最基本的,只有掌握这些类的知识,才 能在分析后续的代码时游刃有余。 ...

    Visual C++ 2005入门经典--源代码及课后练习答案

    Ivor Horton还著有Beginning Visual C++ 6、Beginning C Programming和Beginning Java 2等多部入门级好书。 目录 封面 -18 前言 -14 目录 -9 第1章 使用Visual C++ 2005编程 1 1.1 .NET Framework 1 1.2 CLR 2...

    Visual C++ 2010入门经典(第5版)--源代码及课后练习答案

     ·分享c++程序的错误查找技术,并介绍通用的调试原则讨论每一个windows应用程序的结构和基本元素  ·举例说明如何使用mfc开发本地windows应用程序  ·指导读者用c++和c++/cli设计和创建大量的windows应用程序 ...

    SpringBoot项目高校学科竞赛平台.zip

    SpringBoot项目高校学科竞赛平台的设计与实现是一个基于SpringBoot框架开发的网络服务系统,旨在支持和管理高校内部或跨校的学科竞赛活动。该平台提供了一个集成的环境,用于发布竞赛信息、组织注册、提交作品和评审...

Global site tag (gtag.js) - Google Analytics