Java 内部类详解

一、前言

内部类平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下。从开发的角度来讲,内部类能少用就少用,优先考虑普通类。

二、内部类的基本概念

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。内部类形式如下:

package com.wz.innterclassdemo;

class Outer { // 外部类
    private String msg = "Hello World "; // 普通属性

    class Inner { // 内部类
        public void print() {
            System.out.println(msg);
        }
    }

    public void fun() {
        Inner in = new Inner();
        in.print();
    }
}

public class TestDemo {
    public static void main(String args[]) {
        Outer out = new Outer();
        out.fun();
    }
}

运行结果:

Hello World 

通过如上的代码可以知道:内部类属于在一个类内部定义的新的结构。不过按照类的基本组成来讲,一个类应该由属性和方法所组成,但是这时又多了一个类,这样的结构并不好,所以内部类最大的缺点破坏了程序的结构。

但是内部类本身也有自己的优点,要想发现这个优点,最好的做法是将内部类拿到外面来,变为两个类:

package com.wz.innterclassdemo;

class Outer { // 外部类
    private String msg = "Hello World "; // 普通属性

    public void fun() {
        Inner in = new Inner(this);
        in.print();
    }

    public String getMsg() {
        return this.msg;
    }
}

class Inner { // 内部类
    private Outer out = null;

    public Inner(Outer out) {
        this.out = out;
    }

    public void print() {
        System.out.println(this.out.getMsg());
    }
}

public class TestDemo {
    public static void main(String args[]) {
        Outer out = new Outer();
        out.fun();
    }
}

运行结果:

Hello World 

这时,我们感觉到代码的复杂度变高了。所以,很明显了,内部类的最大优点:可以方便的访问外部类的私有操作,或者是由外部类方便的访问内部类的私有操作。

接着看:

package com.wz.innterclassdemo;

class Outer { // 外部类
    private String msg = "Hello World "; // 普通属性

    class Inner { // 内部类
        private String info = "你好!"; // 内部类私有

        public void print() {
            System.out.println(msg); // 内部类访问外部类
        }
    }

    public void fun() {
        Inner in = new Inner();
        in.print();
        System.out.println(in.info); // 外部类直接调用
    }
}

public class TestDemo {
    public static void main(String args[]) {
        Outer out = new Outer();
        out.fun();
    }
}

之前强调过:访问类中的属性前面都要有“this.”,即:以上的程序中,内部类访问外部类私有属性的时候,应该是“this.msg”才对,但是在内部类使用this表示的只是内部类的当前对象,所以要想表示出外部类的当前对象,使用“外部类.this”来表示:

    class Inner { //  内部类
        public void print() {
            System.out.println(Outer.this.msg);//  内部类访问外部类,Android开发之中,此代码常见
        }
    }

以上的程序都是通过外部类的方法操作内部类,但是如何在不同的类操作内部类呢?
下面给出在外部实例化内部类对象的操作格式:

外部类.内部类 内部类对象 = new 外部类().new 内部类() ;
package com.wz.innterclassdemo;

class Outer { // 外部类
    private String msg = "Hello World "; // 普通属性

    class Inner { // 内部类
        public void print() {
            System.out.println(Outer.this.msg);// 内部类访问外部类
        }
    }
}

public class TestDemo {
    public static void main(String args[]) {
        Outer.Inner in = new Outer().new Inner();
        in.print();
    }
}

但在实际开发中,以上操作基本不会使用:

Outer.Inner in = new Outer().new Inner(); // 这种格式几乎不会出现

一般是通过外部类访问内部类。

但是,如果内部类不希望被外面看见怎么办?那么可以继续进行封装操作:

class Outer { // 外部类
    private String msg = "Hello World "; // 普通属性

    private class Inner { // 内部类
        public void print() {
            System.out.println(Outer.this.msg);// 内部类访问外部类
        }
    }
}

此时,内部类是不能在外部进行对象实例化的。在Android开发之中,这种使用private class定义的内部类是比较常见的。

三、使用static定义内部类

使用static定义的属性和方法,是独立于类之外的,可以在没有实例化对象的时候调用,而static也同样可以进行内部类的定义,而使用了static定义的内部类,则表示为“外部类”,并且只能访问外部类之中static类型的操作。

取得内部类的实例化对象使用的语法如下:

外部类.内部类 对象 = new 外部类.内部类();

此时不再需要先产生外部类对象,再产生内部类对象。

package com.wz.innterclassdemo;

class Outer { // 外部类
    private static String msg = "Hello World "; // 普通属性

    static class Inner { // 内部类 = ”外部类“
        public void print() {
            System.out.println(Outer.msg);// 内部类访问外部类
        }
    }
}

public class TestDemo {
    public static void main(String args[]) {
        Outer.Inner in = new Outer.Inner();
        in.print();
    }
}

运行结果:
Hello World

四、在方法中定义内部类

内部类可以在类的任意位置上进行定义,包括类中、代码块中,或者方法。在开发过程之中在普通方法里面定义内部类的情况是最多的。

package com.wz.innterclassdemo;

class Outer { // 外部类
    private String msg = "Hello World "; // 普通属性

    public void fun() {
        class Inner { // 方法中定义的内部类
            public void print() {
                System.out.println(Outer.this.msg);// 内部类访问外部类
            }
        }
        Inner in = new Inner(); // 产生内部类对象
        in.print();
    }
}

public class TestDemo {
    public static void main(String args[]) {
        new Outer().fun();
    }
}

运行结果:

Hello World 

但是如果一个内部类要定义在方法中,并且要访问方法的参数或者方法中的变量时这些参数或变量前一定要增加一个“final”关键字(注:JDK 1.8及更高的版本可以不加,但实际开发中,JDK1.7及以下版本使用的也比较多,所以我们在开发中一定要加上final关键字)。

package com.wz.innterclassdemo;

class Outer { // 外部类
    private String msg = "Hello World "; // 普通属性

    public void fun(final int x) { // 参数
        final String info = "Hello"; // 变量
        class Inner { // 方法中定义的内部类
            public void print() {
                System.out.println(Outer.this.msg);
                System.out.println(x);
                System.out.println(info);
            }
        }
        Inner in = new Inner(); // 产生内部类对象
        in.print();
    }
}

public class TestDemo {
    public static void main(String args[]) {
        new Outer().fun(30);
    }
}

运行结果:

Hello World 
30
Hello
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值