内部类

匿名内部类

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

只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现

示例

//学校类
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: 张三老师在讲课

使用的形参必须为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 );
    }

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

从作用域的角度理解final的必要性

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

此时外围类中name的值是不会发生改变的,  这就产生了矛盾, 程序自然是不会接受的,所以为了保持参数的一致性,就规定使用final来避免形参的不改变。

匿名类的初始化  

匿名内部类是没有构造器的, 它使用代码块达到构造器的效果, 

都知道抽象类是无法直接new的, 它创建的是子类,  下面代码可以通过编译,说明 创建一个匿名内部类它包含了以下步骤:定义本类 , 继承父类 ,实现类 , 创建实例 

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_;
            }
        };
    }

 普通内部类和静态内部类的区别

普通内部类: 指向外部类, class类型是 Parent.Inner

静态内部类: 不指向某个具体的外部类对象,class的类型是 Parent.Inner

示例

public class InnerClass {
    public static void main(String[] args) {
        /**
         * 创建静态内部类:注意这里是 直接new的 
         */
        Parent.Inner1 i = new Parent.Inner1();
        i.print();
        
        /**
         * 创建普通内部类:注意这里是 p.new 
         */
        Parent p = new Parent();
        Inner2 t =  p.new Inner2();
    }
}

class Parent {
    //静态内部类
    static class Inner1 {
        public void print() {
            System.out.println("in inner1");
        }
    }
    
    //普通内部类
    class Inner2 {
        public void print() {
            System.out.println("in inner2");
        }
    }
}

 

posted @ 2016-10-13 22:52  liuconglin  阅读(225)  评论(0编辑  收藏  举报