Java——内部类

简介: 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();
}


相关文章
|
1月前
|
Java
【Java基础面试二】、个Java文件里可以有多个类吗(不含内部类)?
这篇文章讨论了Java文件中类的定义规则,指出一个Java文件可以包含多个类(不包含内部类),但其中最多只能有一个public类,且如果有public类,它的名称必须与文件名一致。
|
1月前
|
算法 Java
12 Java常用类(一)(内部类+object类+包装类)
12 Java常用类(一)(内部类+object类+包装类)
28 5
|
2月前
|
Java
Java进阶之内部类
【7月更文挑战第13天】Java内部类增进代码组织与封装,允许直接访问外部类成员,包括私有成员。主要有四种类型:成员、静态、局部和匿名内部类。匿名内部类常用于一次性实现接口或扩展类。内部类可隐藏实现细节,减少命名冲突,并在特定上下文中定义辅助类。示例展示了静态和非静态内部类如何在Shape类中封装Circle和Rectangle。使用内部类能提升代码可读性,但可能增加复杂性。
31 6
|
1月前
|
Java
【Java】内部类、枚举、泛型
【Java】内部类、枚举、泛型
|
3月前
|
Java
一篇文章讲明白Java中内部类详解—匿名内部类
一篇文章讲明白Java中内部类详解—匿名内部类
42 2
|
3月前
|
设计模式 Java 编译器
Java中的内部类(如果想知道Java中有关内部类的知识点,那么只看这一篇就足够了!)
Java中的内部类(如果想知道Java中有关内部类的知识点,那么只看这一篇就足够了!)
|
3月前
|
Java 编译器
24. 【Java教程】内部类
24. 【Java教程】内部类
22 2
|
4月前
|
Java 程序员
Java的内部类与匿名类的技术性文章
Java的内部类与匿名类的技术性文章
34 1
|
3月前
|
Java
Java内部类相关内容总结和解读
Java内部类相关内容总结和解读
25 0
|
3月前
|
存储 Java
Java 五种内部类演示及底层原理详解
Java 五种内部类演示及底层原理详解
24 0