04_匿名内部类

匿名内部类(对象)

我们已经使用过匿名对象了,匿名对象的含义是这个对象是没有名字,没有引用指向它

那么如果一个类没有名字,那么这个类就是匿名类(Anonymous Class)

显然一个正常的类是不可能没有名字的,我们今天就来介绍匿名内部类

案例

回顾一下,以往当需要一个子类对象的时候,我们需要分两步走

  • 定义子类继承(实现)父类(接口)
  • 创建子类对象
  • 那么有没有一步直达的方式呢?
    • 我们可以通过局部内部类得到一个实现子类
    • 如果把局部内部类更进一步,变成匿名(局部)内部类呢?

匿名内部类的创建

  • 首先明确两点使用匿名内部类的前提

    • 匿名内部类是特殊的局部内部类,所以匿名内部类必须定义在局部位置
      • 匿名内部类是局部内部类的更进一步
      • 匿名内部类的成员特征、访问特征和局部内部类没有区别
    • 存在一个已定义类或者接口,这里的类可以是具体类也可以是抽象类
  • 语法:

  • class outerClass {
    
        // 定义一个匿名类
        object1 = new Type(parameterList) {
           // 匿名类代码
        };
    }
    
  • 注意右大括号的结尾分号,不可省略

  • 匿名内部类的本质是继承了一个(抽象)类或者实现了接口

匿名内部类对象的使用

  • 直接使用对象去调方法即可
    • 也可以用父类接收,但是父类接收无法调用子类独有方法
  • 当我们只使用一次某类或者某接口的,子类对象,此时用匿名内部类对象,会稍微方便一点
  • 但是,如果要多次访问,匿名内部类对象中的成员,就比较麻烦了
    • 因为每一次访问都得创建一次匿名内部类对象
  • 通常,在只使用一次类、接口的子类对象的情况下,比较适合使用匿名内部类对象来完成
  • 本质:是一个继承了类或者实现了接口的子类匿名对象

小试牛刀

按照要求,补齐代码

要求在控制台输出”HelloWorld”
public class Test{
    public static void main(String[] args) {
        Outer.method().show();
    }
}
interface Inter {
    void show();
}
class Outer {
    
}
public class Test5{
    public static void main(String[] args) {
        Outer.method().show();
    }
}
interface Inter {
    void show();
}
class Outer {
    // -------------改动内容--------------
    public static Inter method() {
        return new Inter() {
            @Override
            public void show() {
                System.out.println("hello world !");
            }
        };
    }
    // -------------改动内容--------------
}

/**
 *  运行结果:
 *      hello world !
 */
  • 开发中的匿名内部类:

    • 方法的实际参数

      • 学习多态的时候我们曾经讲过,可以将父类作为形式参数,而将子类作为实际参数在方法调用的时候传入

        向上转型

      • 匿名内部类的匿名对象就是一个子类匿名对象,所以,可以使用匿名内部类改进以前的做法

        改进前

        package com.wd.day11.tset6.Demo2;
        
        /**
         * @author wangdezhao
         * @date 2021/3/11
         * @description
         */
        public class Demo2 {
            public static void main(String[] args) {
                Father f = new Son();
                // 打印 "哈哈哈哈"
                f.print();
            }
        }
        
        class Father {
            public void print() {
                System.out.println("我是一个父类");
            }
        }
        
        class Son extends Father {
            @Override
            public void print() {
                System.out.println("哈哈哈哈");
            }
        }
        
        
        

        改进后

        package com.wd.day11.tset6.Demo1;
        
        /**
         * @author wangdezhao
         * @date 2021/3/11
         * @description
         *     不需要定义子类,直接可以重写,确实简便了
         */
        public class Test6 {
            public static void main(String[] args
                                   ) {
                // 匿名内部类继承普通类
                Father f = new Father(){
                    @Override
                    public void print(){
                        System.out.println("哈哈哈哈");
                    }
                };
                f.print();
                // 打印 "哈哈哈哈"
                
                
                // 匿名内部类继承抽象类
                AbstractFather af = new AbstractFather() {
                    @Override
                    public void print() {
                        System.out.println("哈哈哈哈");
                    }
                };
                af.print();
                // 打印 "哈哈哈哈"
                
                
                // 匿名内部类继承接口
                IFather ifather = new IFather() {
                    @Override
                    public void print() {
                        System.out.println("哈哈哈哈");
                    }
                };
                ifather.print();
                // 打印 "哈哈哈哈"
                
            }
        }
        
        
        //普通类
        class Father{
            public void print(){
                System.out.println("我是父类");
            }
        }
        
        
        // 抽象类
        abstract class AbstractFather{
            public abstract void print();
        }
        
        
        // 接口
        interface IFather{
            void print();
        }
        
    • 方法体中,return 返回值只会执行一次,如果方法返回一个接口类型的对象,我们也可以使用匿名内部类

      package com.wd.day11.tset6.Demo3;
      
      /**
       * @author wangdezhao
       * @date 2021/3/11
       * @description
       */
      public class Test3 {
          // 一个返回值是IA接口的方法,通过主类Test3的实例化对象去调用
          public IA getIA(){
              return new IA(){
                  @Override
                  public void print() {
                      System.out.println("哈哈哈哈");
                  }
              };
          }
         
          // 主方法
          public static void main(String[] args) {
              Test3 t = new Test3();
              t.getIA().print();
              // 直接打印 重写后的 "哈哈哈哈"
          }
      }
      
      
      interface IA{
          void print();
      }
      
      

通过定义匿名内部类对象,我们可以将上面的两步变为一步。

​ 匿名内部类的前提:

​ 存在一个类或者接口,这里的类可以是具体类也可以是抽象类。

​ 匿名内部类的语法:

​ new 类名或者接口名() {重写方法;}

​ 本质:是一个继承了类或者实现了接口的子类匿名对象

匿名内部类的使用优缺点:

​ 1,当我们只使用一次某类或者某接口的子类对象时,使用匿名内部类,会稍微方便一点

​ 2,如果需要多次访问子类对象的成员,匿名内部类很麻烦。

​ 3,如果访问匿名子类中的独有方法,必须用匿名对象去访问

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
局部内部类和匿名内部类Java中的两种特殊类型的内部类。 局部内部类是定义在方法或者代码块内部的类。它的作用域被限定在所属的方法或代码块内部,不能在外部访问。局部内部类可以访问所属方法或代码块的局部变量,但是这些变量必须声明为final或者事实上的final(在Java 8之后,可以省略final关键字,但是不能对这些变量进行修改)。局部内部类的定义形式如下: ```java public class OuterClass { public void someMethod() { final int localVar = 10; class LocalInnerClass { public void innerMethod() { System.out.println(localVar); } } LocalInnerClass inner = new LocalInnerClass(); inner.innerMethod(); } } ``` 匿名内部类是没有名字的内部类,它直接继承了一个父类或者实现了一个接口。通常用于创建只使用一次的简单类。匿名内部类没有构造方法,因此可以直接通过实例化后的对象进行方法调用。匿名内部类的定义形式如下: ```java public class OuterClass { public void someMethod() { Thread thread = new Thread(new Runnable() { public void run() { System.out.println("Thread is running"); } }); thread.start(); } } ``` 在上述代码中,我们使用匿名内部类实现了Runnable接口,并在Thread类的构造方法中传入了该匿名内部类的实例。 总结一下,局部内部类是定义在方法或代码块内部的类,它的作用域被限定在所属的方法或代码块内部;而匿名内部类是没有名字的内部类,通常用于创建只使用一次的简单类。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值