匿名内部类

为什么有内部类

每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多重继承的解决方案变得更加完整。

如何定义一个匿名内部类

以学校和老师的关系为例

//学校类
class School{

    public static Teacher getTeacher(){

        //匿名内部类
        return  new Teacher(){

            public void teaching(){

                System.out.println("张三老师在讲课");
            }
        };
    }
}

//老师类
abstract class Teacher{
    public  abstract void teaching();
}

//测试类
public class Annoymous {

    public static void main(String[] args) {

        Teacher t = School.getTeacher(); 

        t.teaching();
    }

}

----------------------Output:  张三老师在讲课 
Teacher类是一个抽象类,都知道抽象类是无法直接new的, 所以必须先继承Teacher才能new, 上述代码可以通过编译,说明 创建一个匿名内部类它包含了以下步骤:定义本类 , 继承父类 ,实现类 , 创建实例 缺点它仅能被使用一次,创建匿名内部类时它会立即创建一个该类的实例,该类的定义会立即消失,所以匿名内部类是不能够被重复使用,如果多次调用匿名内部类,建议重新定义类。

注意事项

1.匿名内部类中是不能定义构造函数的。

2.匿名内部类中不能存在任何的静态成员变量和静态方法。

3.使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口

4.匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法

使用的形参必须为final

我们给匿名内部类传递参数的时候,若该形参在内部类中需要被使用,那么该形参必须要为final

为什么呢?

内部类和外围类,编译后是两个class文件, 内部类仅仅保存了对外围类的引用

public class OuterClass {
    public void display(final String name){
        //内部类
        class InnerClass{
            void display(){
                System.out.println(name);
            }
        }
    }

内部类InnerClass获取形参的过程如下:

第一步: 把形参进行值拷贝

public class OuterClass$InnerClass {
    public InnerClass(String name){
        this.InnerClass$name = name;
    }

第二步:使用内部类的属性

 public void display(){
        System.out.println(this.InnerClass$name + "----" + this.InnerClass$age );
    }

内部类并不是直接调用方法传递的参数,而是利用自身的构造器对传入的参数进行备份,调用的实际上时自己的属性而不是外部方法传递进来的参数。

进一步的分析:

从作用域的角度:   外部方法的参数name, 作用域是整个外围类,当然也包括内部类, 内部类中使用的name,  作用域是整个内部类  , 如果在内部类中,对name值进行了修改,

此时外围类中name的值是不会发生改变的,  这就产生了矛盾, 程序自然是不会接受的

所以为了保持参数的一致性,就规定使用final来避免形参的不改变。

匿名类的初始化

匿名内部类是没有构造器的!那怎么来初始化匿名内部类呢?使用代码块达到构造器的效果

public class OutClass {
    public InnerClass getInnerClass(final int age,final String name){
        return new InnerClass() {
            int age_ ;
            String name_;
            //构造代码块完成初始化工作
            {
                    age_ = age;
                    name_ = name;
                }
            }
            public String getName() {
                return name_;
            }

            public int getAge() {
                return age_;
            }
        };
    }
时间: 2024-08-05 13:42:37

匿名内部类的相关文章

IT十八掌作业_java基础第七天_匿名内部类、异常、包和jar

利用白富美接口案例,土豪征婚使用匿名内部类对象实现. 2.定义三角形类Trianle,里面包含三个int类型属性,分别表示三条边的长度, 构造三角形对象时,任意两边之和是否大于第三边,如若不成立,抛出自定义异常. 3.Person类中增加birthday属性,对setBirthday(int ,int , int )方法进行异常处理, 要求年有效.月有效.日有效.年月日指定的具体日期有效,对不同情况分别抛出不同的异常. 4.将类定义到指定的包下.com.it18zhang,编译之后,打成jar文

包、修饰符、内部类、匿名内部类(java基础知识十)

1.package关键字的概述及作用 * A:为什么要有包     * 将字节码(.class)进行分类存放  * B:包的概述     *   * C:包的作用     * 包名要定义在第一行,     * 包名.*这个包下所有的类都可见     * 具体的类比较好,能提高效率 2.包的定义及注意事项 * A:定义包的格式 * package 包名; * 多级包用.分开即可* B:定义包的注意事项 * A:package语句必须是程序的第一条可执行的代码 * B:package语句在一个jav

我的学习之路_第三章_匿名内部类

final: final是最终修饰符,可以修饰类.成员方法.变量. final修饰的类无法被继承. final修饰的方法无法被重写. final修饰的变量无法被再次赋值,变为了常量. final修饰的引用数据类型变量,可以修改对象里面的属性内容,不可改变地址值 final修饰的成员变量,不能使用默认值,没有意义,必须在创建对象之前完成赋值. static: 静态修饰符,被static修饰的内容属于类不专属于某个对象,多个对象共享使用这一个成员 使用static修饰的成员可以用类名直接访问,建议这

“匿名内部类”的使用场合举例

package com.sxt.set6; import java.util.Comparator; import java.util.HashSet; /* * TreeSet 有序的 二叉树(红黑数) */ import java.util.Set; import java.util.TreeSet; /* * 匿名内部类 * 使用场合:只需要创建一次对象,就不在使用了,没有必要提供专门的实现类(不使用外部比较器) * */ public class TestStudent { public

java9-9 匿名内部类

1. 匿名内部类 就是内部类的简化写法. 前提:存在一个类或者接口 这里的类可以是具体类也可以是抽象类. 格式: new 类名或者接口名(){ 重写方法; } new Xxx()是创建了一个对象,而抽象类和接口不能被new修饰, 所以,这里的东西的本质已经变了 那么,本质是什么呢? 是一个继承了该类或者实现了该接口的子类匿名对象. 1 interface Inter4{ 2 public abstract void show(); 3 public abstract void show2();

java 内部类3(匿名内部类)

匿名内部类: 1.没有类名的类就叫匿名内部类 2.好处:简化书写. 3.使用前提:必须有继承或实现关系......不要想着你自己没有钱你没可是你爸有 4.一般用于于实参.(重点) class Outer{ class Inner{ public void show(){ System.out.println(“内部累的show方法”); } } public void print(){ new Inner().show(); } }

Java内部类:匿名内部类(四)

Java内部类分为4个部分进行阐述,分别为概览.成员内部类.局部内部类和匿名内部类. 在本文中是Java内部类的匿名内部类,主要讲述匿名内部类的概念.匿名内部类的好处.匿名内部类的使用前提.和匿名内部类的应用场景. 1.匿名内部类的概念 没有类名的类就称作为匿名内部类 2.匿名内部类的好处 简化书写 3.匿名内部类的使用前提 必须存在继承或者实现关系才能使用 4.匿名内部类的应用场景 匿名内部类一般是用于实参 示例代码: package com.rk.innerclass; public cla

面向对象、匿名内部类

1 内部类 1.1 内部类的概述 将类定义在另一个类的内部则成为内部类.其实就是类定义的位置发生了变化. 在一个类中,定义在类中的叫成员变量,定义在函数中的叫成员函数,那么根据类定义的位置也可以分为成员内部类和局部内部类. 备注:内部类生产的class文件为 “外部类$内部类”,为了标明该内部类是属于具体哪个外部类的. 1.2 成员内部类的访问方式 内部类可以直接访问外部类的成员属性.(孙悟空相当于内部类飞到牛魔王的肚子里面去). 外部类需要访问内部类的成员属性时需要创建内部类的对象. 在外部类

Java学习(十六)、成员内部类,静态内部类,匿名内部类,局部内部类

定义:将一个类定义在另一个类的内部.内部的类称为内部类; public class Outer{ class inner{ //省略 } } 特点: ①   内部类可以很好的实现隐藏,可以使用protected,private修饰符; ②   内部类可以直接访问外部类的所有成员,包括私有成员; ③   外部类不能直接访问内部类的成员,必须首先要建立内部类的对象才能访问; ④   内部类可以解决一些问题,比如间接的去实现多继承.可以避免修改接口而实现同一个类中两种同名方法的调用; 成员内部类及应用