内部类, 静态内部类, 局部类, 匿名内部类的解析和区别

内部类:

    成员内部类可访问外部类所有的方法和成员变量。

    不能有静态的方法和成员变量。

静态内部类:

    只能访问外部类的静态成员变量与静态方法。

    静态内部类的非静态成员可访问外部类的静态变量,而不可访问外部类的非静态变量。

匿名内部类:

    没有类名,没有class关键字也没有extends和implements等关键字修饰。

    类的定义和对象的实例化同时进行。
--------------------- 

众所周知,外部顶级类的类名需和类文件名相同,只能使用public和default。而内部类是指在外部类的内部再定义一个类,类名不需要和文件名相同。内部类可以是静态static的,也可用public,default(包限定),protected和private修饰。

内部类:

概念:

我们所说的内部类,官方的叫法是嵌套类(Nested Classes)。嵌套类包括静态内部类(Static Nested Classes)和内部类(Inner Classes)。而内部类分为成员内部类,局部内部类(Local Classes)和匿名内部类(Anonymous Classes)。

image.png

内部类是一个编译是的概念,一旦编译成功,就会成为完全不同的两个类,分别为outer.class和outer$inner.class类。所以内部类的成员变量/方法名可以和外部类的相同。

内部类有什么作用?

1.内部类可以很好的实现隐藏
一般的非内部类,是不允许有 private 与protected权限的,但内部类可以
2.内部类拥有外围类的所有元素的访问权限 (private修饰也能访问)
3.可是实现多重继承 (让多个内部类分别继承多个其他类,使外部类可以同时获取多个其他类的属性)
4.可以避免修改接口而实现同一个类中两种同名方法的调用。(外部类继承,让内部类实现接口)

静态内部类:

形如:

public class OuterClass {
    private String name;

    static class StaticInerCls{
        private String name;
    }
}

静态内部类除了访问权限修饰符比外围类多以外, 和外围类没有区别, 只是代码上将静态内部类组织在了外部类里面。静态内部类不能访问外部类的非公开成员。
创建静态内部类:以Class.Iner的形式

OuterClass.StaticInerCls staticInerCls = new OuterClass.StaticInerCls();  

非静态内部类:

非静态内部类能访问外部类的一切成员, 包括私有成员。外部类虽然不能直接访问内部类的成员, 但是可以通过内部类的实例访问内部类的私有成员。

成员内部类:

形如:

public class OuterCls {
    private String name;
    public String getName(){
        return name;
    }

    class InerCls{
        private String name;

        public String getName(){
            return name;
        }
    }

}

成员内部类可以直接使用外部类的所有成员和方法,即使是private修饰的。而外部类要访问内部类的所有成员变量和方法,内需要通过内部类的对象来获取。(谁叫它是亲儿子呢?) 要注意的是,成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的。
创建内部类对象方法,以object.new Iner的形式:

OuterCls outerCls = new OuterCls();
OuterCls.InerCls inerCls = outerCls.new InerCls();  

成员内部类不能有static修饰的成员,但是却允许定义常量。

public class OuterClass {
    private String name;

    static class StaticInerCls{
        private String name;
    }

    class InerCls{
        private String name;
        private static int id;    //不允许,会报错
        private static final int TYPE = 0;   //允许
    }
}

局部内部类:

指内部类定义在方法体内,只能在该方法或条件的作用域内才能使用,退出这写作用域就无法引用。

public class OuterCls {
    private String name;
    public String getName(){
        return name;
    }

    public void getInerCls(){
        class InerCls{
            private String name;

            public String getName(){
                return name;
            }
        }
    }

}

作为非静态内部类的一种特殊形式, 非静态内部类的所有限制对局部类同样成立。局部类不仅可以访问外部类的所有成员,还可以访问方法体的局部变量,但必须是final修饰的局部变量。

为什么局部类访问局部变量,变量必须加上final?

场景:

    public static void main(String[] args){
        Outer out = new Outer();
        Object obj = out.method();
    }

    Object method(){
        int localVariable = 0;
        class Inner{
            void println(){
                System.out.println("localVariable " + localVariable);
            }
        }
        Object in = new Inner();
        return in;
    }
}

这里的localVariable会变红,提示需要给localVariable变量加final修饰。
解析:这是作用域的问题。在方法method执行完成后,局部变量value就失效了,而在new Inner()产生的in对象还存在obj的引用,这样对象就访问了一个不存在的变量,是不允许的。iner还存在,在外面和后续调用该局部变量时,这个局部变量可能已经失效了。但为什么加上final就可以保证能访问呢?这里Java采用了一种copy local variable的方法实现,定义为final的变量,会拷贝一份存到局部内部类中,后续使用持续维护这个对象在生命周期内,所以可以继续访问。

注:final可以修饰的范围有类,方法,属性。修饰类,该类不可以被继承;修饰方法,该方法不可以被子类重写;修饰变量,该变量值不能被修改。

匿名内部类:

为了免去给内部类命名,或者只想使用一次,就可以选择使用匿名内部类。

    public void countDown(){
        new Thread(){
            @Override
            public void run() {

            }
        }.start();
    }



作者:翻滚吧李博
链接:https://www.jianshu.com/p/f0fdea957792
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值