Java——内部类

3 内部类

内部类是 Java 中很特殊的一个语法。一方面,内部类能够一定程度上的减少代码量,并且能够为程序员提供一些语法方面的比较方便的功能。另一方面来说,内部类有可能带来非常古怪的语法,这些语法会造成代码的可读性下降。因此,内部类是一把双刃剑。从规范上说,我们并不提倡程序员过多的使用内部类,不过依然应该了解一些内部类的基本语法和部分内部类的使用方法。

Java 中的内部类分为四种:成员内部类、静态内部类、局部内部类、匿名内部类,我们下面对这四种内部类分别进行介绍。

3.1 成员内部类

class MyOuterClass{
    private int value;
    private class InnerClass{
    public void m(){
        System.out.println(value);
        }
    }
}

上面这段代码演示了如何定义一个成员内部类。

首先,定义成员内部类的位置,应该在某一个类的里面,在任何一个函数的外面(也就是定义成员变量的位置)。

其次,由于成员内部类定义在外部类的内部,因此在成员内部类中可以访问外部类的私有成员。例如,上面的程序中,在 InnerClass 的 m 方法中,就访问了外部类 MyOuterClass的私有属性 value。

第三,成员内部类可以作为 private 的。之前我们学习修饰符的时候曾经提过,private不能修饰类。但是 private 可以修饰成员内部类,这表示只能在 MyOuterClass 的内部使用InnerClass 类。

编译上面的程序,会在相应的目录中生成两个.class 文件:一个 MyOuterClass.class 文件和一个MyOuterClass$InnerClass.class 文件。这说明,在编译时,内部类也会生成独立的.class文件,换句话说,内部类也是独立的类。

最后要说明的一点,由于成员内部类必须与外部类某一个对象相关联,因此成员内部类中不能定义静态方法。

3.2 静态内部类

静态内部类与成员内部类相似,只有一点不同:在定义成员内部类之前,增加一个 static关键字,则定义的内部类就成为一个静态内部类。示例代码如下:

class MyOuterClass{
    //成员内部类
    class MemberInner{}
    //静态内部类
    static class StaticInner{}
}

需要说明的是,static 关键字不能够用来修饰类,但是能够用来修饰内部类。接下来我们看一下静态内部类以及成员内部类对外部类成员的访问。

class MyOuterClass{
    int value1 = 100;
    public void m1(){}
    static int value2 = 200;
    public static void m2(){}
    class InnerClass1{
        public void f1(){
        //成员内部类中能够访问外部类的静态成员以及非静态成员
        System.out.println(value1);
        System.out.println(value2);
        m1();
        m2();
    }
        //!public static void f2(){}
        //编译出错,成员内部类不能定义静态方法
}
static class InnerClass2{
    public void f1(){
    //静态内部类中只能访问外部类的静态成员
    //System.out.println(value1); 出错!
    System.out.println(value2);
    //! m1();
    m2();
    }
    //静态内部类中可以定义静态方法
    public static void f2(){}
    }
}

成员内部类中不能定义静态方法;成员内部类中能够访问外部类的所有静态以及非静态的成员;

静态内部类中可以定义静态方法,静态内部类中只能访问外部类的静态成员(即访问外部类的静态属性或者调用外部类的静态方法。)

至于如何创建静态内部类的对象,也分两种情况

第一种情况,在外部类中,可以直接创建内部类的对象。(在上面的例子中,指的是在MyOuterClass 类中,可以直接创建内部类的对象)。这种情况与成员内部类的情况相同,在此不再赘述。

第二种情况,在外部类的外部创建对象。以上面的例子来说,也就是在 MyOuterClass类的外部如何创建内部类对象。这种情况下,静态内部类比成员内部类要简单的多。直接使用“外部类.内部类”的方式就能够创建。

3.3 局部内部类

所谓局部内部类,指的是定义在方法内部的类。

class Outer{
    private int value = 100;
    private static int value2 = 200;
    public void m(){
        int localValue = 300;
        class Inner{
            public void f(){
            System.out.println(value);
            System.out.println(value2);
        }
    }
        Inner in = new Inner();
            in.f();
    }
}

与局部变量一样,局部内部类访问范围就是在方法内部。也就是说,定义的这个 Inner类只能在 m 方法内部使用,而无法在 m 方法外部使用。

3.4 匿名内部类

匿名内部类是一种特殊的局部内部类。如果一个局部内部类满足这样两个特点:

1、该内部类继承自某个类或者实现某个接口;

2、该内部类在整个方法中只创建了一个对象。满足这两个特点的局部内部类就能够改写成匿名内部类。

public static Teacher getTeacher(int n){
    //Jim 依然采用局部内部类的写法
    class Jim implements Teacher{
    public void teach(){
        System.out.println(“Jim teach”);
    }
}
//匿名内部类
if (n == 10) return new Teacher(){
    public void teach(){
        System.out.println(“Tom teach”);
        }
    };
    else return new Jim();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值