码迷,mamicode.com
首页 > 其他好文 > 详细

匿名内部类

时间:2016-10-13 23:31:08      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:

为什么有内部类

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

如何定义一个匿名内部类

以学校和老师的关系为例

//学校类
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_;
            }
        };
    }

 

匿名内部类

标签:

原文地址:http://www.cnblogs.com/liuconglin/p/5958526.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!