Java基础——内部类详解(成员内部类、局部内部类、匿名内部类、静态内部类)

内部类包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类

  • 成员内部类
  1. 成员内部类定义为位于另一个类的内部,成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括 private 成员和静态成员)。
class Outer{
    private double a = 0;
    public static int b =1;
    public Outer(double a) {
        this.a = a;
    }
    class Inner {     //内部类
        public void fun() {
            System.out.println(a);
            System.out.println(b);

 

        }
    }
}
  1. 当成员内部类拥有和外部类同名的成员变量或者方法时,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:外部类. this .成员变量
  2. 在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问。
  3. 成员内部类是依附外部类而存在的,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象。创建成员内部类对象的一般方式如下:

```java
class Outter{
    private double a = 0;
    public static int b =1;
    public Outter(){}
    public Outter(double a) {
        this.a = a;
        Inner inner = new Inner();
        inner.fun();     //调用内部类的方法
    }
    class Inner {     //内部类
        int b = 2;
        public void fun() {
            System.out.println(a);
            System.out.println(b);            //访问内部类的b
            System.out.println(Outter.this.b);//访问外部类的b
        }
    }
}
public class Main{
    public static void main(String[] args) {
        Outter outter = new Outter(); 
        Outter.Inner inner = outter.new Inner(); //创建内部类的对象
    }
}
  • 局部内部类
    局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。
class Outter {
    private int outter_a = 1;
    private static int static_b = 2;
    public void test1(){
        int inner_c =3;
        class Inner {
            private void fun(){
                System.out.println(outter_a);
                System.out.println(static_b);

 

                System.out.println(inner_c);
            }
        }
        Inner  inner = new Inner(); //创建局部内部类
        inner.fun();
    }
    public static void test2(){
        int inner_d =3;
        class Inner {
            private void fun(){
                 System.out.println(outter_a); //编译错误,定义在静态方法中的局部
类不可以访问外部类的实例变量
                System.out.println(static_b);
                System.out.println(inner_d);
            }
        }
        Inner  inner = new Inner();
        inner.fun();
    }
}
  • 匿名内部类
    匿名内部类只没有名字的内部类,在日常开发中使用较多。使用匿名内部类的前提条件:必须继承一个父类或实现一个接口。
interface Person {
    public void fun();
}
class Demo {
    public static void main(String[] args) {
         new Person() {
            public void fun() {
                System.out.println("hello,word");
            }
        }.fun();
    }
}
  • 静态内部类
    静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字 static 。静态内部类是不需要依赖于外部类的,并且它不能使用外部类的非 static 成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static 成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。
class Outter {
    int a = 1;
    static int b = 2;
    public Outter() {
    }
    static class Inner {
        public Inner() {
            System.out.println(a);//报错,静态内部类不能访问非静态变量
            System.out.println(b);
        }
    }
}
public class Main{
    public static void main(String[] args) {
        Outter.Inner inner = new Outter.Inner();
    }
}
  • 内部类的优点:
  1. 内部类不为同一包的其他类所见,具有很好的封装性;
  2. 匿名内部类可以很方便的定义回调。
  3. 每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实
    现,对于内部类都没有影响。
  4. 内部类有效实现了“多重继承”,优化 java 单继承的缺陷。
    局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上 final ?
public class Main {
    public static void main(String[] args)  {
    }
    public void fun(final int b) {
        final int a = 10;
        new Thread(){
            public void run() {
                System.out.println(a);
                System.out.println(b);
            };
        }.start();
    }
}

对于变量 a 可以从生命周期的角度理解,局部变量直接存储在栈中,当方法执行结束后,非 final
的局部变量就被销毁,而局部内部类对局部变量的引用依然存在,如果局部内部类要调用没有
final 修饰的局部变量时,就会造成生命周期不一致出错。

对于变量 b ,其实是将 fun 方法中的变量 b 以参数的形式对匿名内部类中的拷贝(变量 b 的拷贝)进行赋值初始化。在 run 方法中访问的变量 b 根本就不是 test 方法中的局部变量 b ,而是一拷贝值,所以不存在生命周期不一致的问题,但如果在 run 方法中修改变量 b 的值会导致数据不一致,所以需要加 final 修饰。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byg_qlh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值