现在的位置: 首页 > 综合 > 正文

java学习笔记 4种内部类小结

2014年07月17日 ⁄ 综合 ⁄ 共 2611字 ⁄ 字号 评论关闭

内部类,顾名思义,就是在内部定义的类,可以定义在类的内部,也可以定义在方法的内部

java中得内部类分为四种:1、静态内部类,2、成员内部类,3、局部内部类,4、匿名内部类

一、静态内部类 static inner class

静态内部类只能访问外部类静态的属性和方法,只有内部类可以定义为静态的,换言之,一个类如果定义为静态的,必然是内部类

简单的测试类如下,包括了如何定义以及如何使用:

/**
 * Created by charleszhu on 14-2-16.
 * 测试静态内部类
 */
class StaticInner{

    private static int a = 4;

    // 定义一个静态内部类
    public static class Inner{
        // 只能调用静态属性和方法
        public void test(){
            System.out.println(a);
        }

    }

}

public class StaticInnerClassTest {

    public static void main(String[] args) {
        // 创建内部类实例的方法,必须从通过外部类.静态内部类的方式才可以创建
        StaticInner.Inner inner = new StaticInner.Inner();
        inner.test();
    }

}

编译之后,内部类的class文件命名为 StaticInner$Inner.class。

二、成员内部类

调用方式和静态内部类不同,因为是非静态的,所以可以使用非静态的方法和属性

简单测试用例:

/**
 * Created by charleszhu on 14-2-16.
 * 测试成员内部类
 */
class MemberInner{

    private int a = 4;

    public class Inner2{
        
        private int a = 5;

        public void doSomething(){
            // 因为是非静态的,所以可以访问非静态的类
            System.out.println("I am invoked!! a=" + a);
            //当内部类有与外部类同名的变量,而又想访问外部的变量时;
            System.out.println(MemberInner.this.a);
        }

    }

}

public class MemberInnerClassTest {

    public static void main(String[] args) {

        //成员内部类的调用和静态内部类的方法有所不同,静态内部类可以通过类名直接调用,因为静态内部类是属于外部类本身的。可以像调用静态方法一样调用
        // 而成员内部类是属于对象的,需要new
        MemberInner.Inner2 inner2 = new MemberInner().new Inner2();
        inner2.doSomething();

    }

}

当内部类有与外部类同名的变量,而又想访问外部的变量时,需要从外部类开始访问 

System.out.println(MemberInner.this.a);

如果要在外部类中得某个方法创建内部类的实例

Inner2 inner2 = this.new Inner2();//此处不用写作MemberInner.Inner,应为内部可看做同级

三、局部内部类(用的最少的类)是为了第四种内部类,匿名内部类做铺垫:定义在方法中,不能加访问修饰符,且只能访问方法中的final类型的变量

/**
 * Created by charleszhu on 14-2-17.
 */
class LocalClass{

    private int a = 4;

    public void test(){
        // 定义局部内部类
        class Inner3{

            final int b= 4;

            public void doSomething(){
               // 只能访问final类型的变量
               System.out.println("LocalInnerClass b=" +4);

            }

        }
        // 内部类无法在外部使用,只能在方法内部定义使用
        Inner3 inner3 = new Inner3();
        inner3.doSomething();
    }
}

public class LocalInnerClassTest {

    public static void main(String[] args) {
        
        LocalClass localClass = new LocalClass();
        //如此才能让Test方法中的Inner3的doSomeThing执行
        localClass.test();
        
    }
    
}

四 、匿名内部类:是使用最多的一种内部类:是表示一个没有名字的特殊的局部内部类类,所以,没有构造方法,也没有class关键字

但是:匿名内部类会隐士的继承一个类或者实现一个借口,具体实现了什么接口或者继承了什么类,要看test(new Date(){//可以重写父类方法 }),中new之后是什么类或者接口

此处是Date,则生成的匿名内部类就是Date的子类

import java.util.Date;

/**
 * Created by charleszhu on 14-2-17.
 */
public class AnonymousInnerClassTest {

    public String get(Date date){

        return date.toString();

    }

    public static void main(String[] args) {

        AnonymousInnerClassTest test = new AnonymousInnerClassTest();

        // 此处做了2件事儿:1定义了一个匿名内部类,2这个内部类继承了Date这个类,所以生成的实例是一个继承自Date类的子类的实例,
        // 到底继承了什么或是实现了什么,就看new后面是什么类或者接口
        String str = test.get(new Date(){
             // 因为这个内部类继承了Date这个类,所以可以重写其中的方法,重写我们要用的方法
            @Override
            public String toLocaleString() {
                return "hello world";
            }
        });

        // 此时结果应该输出的是hello world
        System.out.println(str);

    }

}

结果输出为:hello world

get(new Date()) 和get(new Date(){ })

是两个完全不同的意思,前者是新建了一个Date对象,传递给了方法

后者是新建了一个继承自Date匿名内部类,并且创建一个对象实例,传给方法。

内部类 在日常开发用的不是很多,但了解,对将来学习框架,阅读别人的代码,无疑是有好处的。

抱歉!评论已关闭.