java的内部类详细介绍

什么是内部类

把一个类的定义在另一个类定义的内部,即叫内部类,内部类有几种类型,内部类可以访问外部的所有成员(因为内部类会保存一个外部类的引用,这是编译器帮我们做的事情)
内部类可以定义外部内中,与外部类成员变量同级,这是见得比较多的。也可以定义在方法中,你几乎可以在任意的位置中定义内部类,只是对内部类的可见性会有影响。这个后面我会举例具体说明。

内部类种类

普通内部类:
嵌套类:
匿名内部类

为什么要使用内部类

1.可重命名和隐藏性:当一个类,一般不需要被别的类(除该外部类之外)引用时,可以考虑将其定义为内部类。如果内部类有有一个名字相同的外部类也是不会影响的。
2.多继承我们知道java中是单继承,多实现的。现在如果需要一个类去继承2个抽象类或者具体类,这对与一般的类是无法做到的,但是如果借助于内部类就可以做到了,即外部类实现继承一个类,在定义一个内部类继承一个类。由于外部类可以实例化内部类。虽然不是类似与c++那种多继承,但是通过内部类,还是可以使其具有继承带来的部分特性。另外外部类可以和内部类实现同样的接口,基于多肽的特性,可以设计出非常精妙的结构。

内部类

一般的内部类定义在于字段同级,内部类的创建必须先创建其外部类的对象,方可由外部类通过外部类名.new 内部类名(),进行实例化。内部类可以访问外部类所有的成员变量,即使外部类成员变量时私有的*内部类中不允许定义静态变量*,允许嵌套定义内部类。具体用法如下

package com.innerclass;

interface Increment{
     void increment();
}

public  class OuterClass implements Increment{
    private int value;
     private class InnerClass implements Increment{
        //在普通的内部类中不可定义静态变量
        private  int i;
        //嵌套定义内部类
        class NestDefineInnerClass implements Increment{

            public NestDefineInnerClass() {
                System.out.println(" i am a nest Innerclass");
            }

            @Override
            public void increment() {
                System.out.println(++i);
                System.out.println(++value);

            }

        }


        public InnerClass() {
            System.out.println("i am innerClass");
        }

        public InnerClass(int i) {
            super();
            this.i = i;
        }

        @Override
        public void increment() {
            System.out.println(++value);
        }
        /**
         * 在内部类中返回外部类的引用
         * @return
         */
        public Increment getOuterClass(){
            return OuterClass.this;
        }



    }
    @Override
    public void increment() {
        System.out.println(++value);
    }

    /**
     * 在外部类中提供一个获取内部类的方法
     * @return
     */
    public Increment getInnerClass(){
        return new InnerClass();
    }



    public static void main(String[] args){
        OuterClass oc = new OuterClass();
        OuterClass.InnerClass ic = oc.new InnerClass();
        OuterClass.InnerClass.NestInnerClass oin = ic.new NestInnerClass();
    }
}

内部类定义在方法中:定义在方法中的内部类可以访问其外部类和方法中的变量。但是该类的作用于仅限在在方法中,意思是在方法外面无法实例化该内部类类型的对象,在方法外,该对象不可见,但不意味这不可以,例如这里下面的例子还是可以利用多肽使其发挥作用的。

public Increment functionInnerClass(int j){
        class FunctionInnerClass implements Increment{

            @Override
            public void increment() {
                System.out.println(j);
            }

        }
        return new FunctionInnerClass();
    }

匿名内部类

匿名内部类:对象的创建和定义结合在一起。
其实创建的是一个父类类型的引用,匿名内部类重新定义自己的构造方法。因为它没有名字,下面我们看下如何使用匿名内部类

    public Increment anonymousInnerClass(){
        return new Increment() {

            @Override
            public void increment() {
                System.out.println("i am a anonymous inner class");
            }
        };
    }

这里返回的是Increment类型的对象,Increment类型是一个接口,这里定义的即是一个匿名内部类,无论是实现的接口,还是普通的类。都是向上转型。如果在匿名内部类中使用外部函数或外部类中变量,必须声明为final,或者不可再给其重新赋值。否则无法通过编译。

嵌套类

不需要和外部类有联系,嵌套类使用static修饰,
创建嵌套类不需要其先创建其外部类对象,
不能访问外部内中非静态的成员。
嵌套类可以定义静态的成员。

 public static class NestInnerClass implements Increment{
         static int i=1;

        @Override
        public void increment() {
            System.out.println(i++);
        }
}

实例化对象

OuterClass.NestInnerClass nc = new NestInnerClass();

这里写图片描述
内部类和外部类之间生成的class文件时通过$符号分隔的。

内部类使用中会出现的问题

内部类使用不当很容易引起内存泄露,原因是内部类持有外部类的引用,如果内部类没被回收,外部内也无法回收。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值