zoukankan      html  css  js  c++  java
  • JAVA学习笔记--匿名内部类

      匿名内部类,即没有名字的内部类。

      我们在编写JAVA程序时,往往要创建很多类,类是可以被重复使用的。但有时,我们创建了一个类,却只需要使用该类一次,那么单独为其编写一个类就显得有些麻烦,这时可以使用匿名内部类来编写这个类,匿名内部类只能使用一次。

    · 匿名内部类没有名字,因而没有构造器;

    · 使用匿名内部类有个前提条件:必须继承一个父类或实现一个接口。

    匿名内部类可以通过以下语句来创建:

      new InterfaceName(){......};   

    或 new SuperClassName(){......};   

    {}中是匿名内部类的具体实现。

    下面用几个例子来展示一下匿名内部类的使用

    1)没有使用匿名内部类的普通方式:

    package com.tongye.anonymous;
    
    abstract class BaseClass{
        abstract public void printMessage();
    }
    
    class TestClass extends BaseClass {
        public void printMessage(){
            System.out.println("匿名内部类测试");
        }
    }
    
    public class AnonymousClass {
        public static void main(String[] args){
            TestClass testClass = new TestClass();
            testClass.printMessage();
        }
    }
    
    /* output:
    匿名内部类测试
    */

      本例没有使用匿名内部类,创建一个新的类继承了抽象类,并实现了抽象类的方法。显然,这个新类可以被重复调用,也可以被继承。

    2)使用匿名内部类方式1

    package com.tongye.anonymous;
    
    abstract class BaseClass{
        abstract public void printMessage();
    }
    
    public class AnonymousClass {
        public static void main(String[] args){
            BaseClass testClass = new BaseClass(){
                public void printMessage(){
                    System.out.println("匿名内部类测试");
                }
            };
            testClass.printMessage();
        }
    }
    /* output:
    匿名内部类测试
    */

      这个例子看上去好像是通过 new 操作符创建了一个抽象类的实例。但我们知道,抽象类是不能通过new操作符来创建实例的,这其实是一个假象,而且和普通的类的实例化写法也不一样,后面有 {} 。这里其实是创建了一个匿名内部类,{}里面的部分就是匿名内部类的实现细节。这个匿名类继承了抽象类BaseClass,它实现了BaseClass抽象类的抽象方法,当然,还可以往里面添加自己的方法体。

    3)使用匿名内部类方式2

    package com.tongye.anonymous;
    
    abstract class BaseClass{
        abstract public void printMessage();
    }
    
    public class AnonymousClass {            
        public BaseClass testClass(){          // 创建一个BaseClass类型的方法testClass(),其返回值类型是BaseClass类型
            return new BaseClass(){            // 创建一个继承自BaseClass的匿名类的对象
                public void printMessage(){
                    System.out.println("匿名内部类测试");
                }
            };
        }
            
        public static void main(String[] args){    
            AnonymousClass anonymous = new AnonymousClass();
            anonymous.testClass().printMessage();
        }
    }
    /* output:
    匿名内部类测试
    */

      这个例子也用到了匿名内部类,只是这里的实现方式与2)中的有些不一样。在本例中,先创建了一个BaseClass类型的方法testClass(),然后,方法 testClass()使用匿名内部类返回了一个实现了接口BaseClass的类的对象。匿名类的具体实现仍然是在{}中。

    4)使用匿名内部类继承一个具有带参构造器的父类

    package com.tongye.anonymous;
    
    class BaseClass{
        private int x;
        
        public BaseClass(int i){
            x = i;
        }
        
        public void getx(){
            System.out.println(x);
        }
    }
    
    public class AnonymousClass {            
        public BaseClass baseClass(int x){             // 创建一个BaseClass类型的方法baseClass(),其返回值类型是BaseClass类型
            return new BaseClass(x){                // 创建一个继承自BaseClass的匿名类的对象
                public void getx(){
                    System.out.println("匿名类测试");
                    super.getx();
                }
            };
        }
            
        public static void main(String[] args){    
            AnonymousClass anonymous = new AnonymousClass();
            BaseClass baseClass = anonymous.baseClass(10);
            baseClass.getx();
        }
    }
    /* output:
    匿名内部类测试
    10
    */
    

       如果一个匿名内部类继承了一个只含有带参构造函数的父类,则创建它的时候,必须带上这些参数,并且在实现的过程中使用super关键字调用相应的内容。尽管这里的BaseClass类是一个有具体实现的普通类,但是它还是被其导出类当做公共“接口”来使用。

      如果想要在匿名内部类使用一个在其外部定义的对象,则必须保证其参数是final的。

      匿名内部类与继承有些相似,但相对普通的继承而言,又有些限制。匿名内部类既可以扩展类,又可以实现接口,但是不能两者兼备;而且如果实现接口,也只能实现一个接口。

  • 相关阅读:
    Linux编程 22 shell编程(输出和输入重定向,管道,数学运算命令,退出脚本状态码)
    mysql 开发进阶篇系列 46 物理备份与恢复( xtrabackup的 选项说明,增加备份用户,完全备份案例)
    mysql 开发进阶篇系列 45 物理备份与恢复(xtrabackup 安装,用户权限,配置)
    mysql 开发进阶篇系列 44 物理备份与恢复( 热备份xtrabackup 工具介绍)
    Linux编程 21 shell编程(环境变量,用户变量,命令替换)
    Linux编程 20 shell编程(shell脚本创建,echo显示信息)
    mysql 开发进阶篇系列 43 逻辑备份与恢复(mysqldump 的基于时间和位置的不完全恢复)
    Linux编程 19 编辑器(vim 用法)
    (网页)angularjs中的interval定时执行功能(转)
    (网页)在SQL Server中为什么不建议使用Not In子查询(转)
  • 原文地址:https://www.cnblogs.com/tongye/p/6802310.html
Copyright © 2011-2022 走看看