Java程序员必备基础:内部类解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java程序员必备基础:内部类解析相关的知识,希望对你有一定的参考价值。

前言

整理了一下内部类的相关知识,算是比较全,比较基础的,希望大家一起学习进步。Java程序员必备基础:内部类解析_匿名内部类

一、什么是内部类?

在Java中,可以将一个类的定义放在另外一个类的定义内部,这就是内部类。内部类本身就是类的一个属性,与其他属性 定义方式一致。

一个内部类的例子:

  1. public class Outer

  2. private int radius = 1;
  3. public static int count = 2;

  4. public Outer()

  5. class inner
  6. public void visitOuter()
  7. System.out.println("visit outer private member variable:" + radius);
  8. System.out.println("visit outer static variable:" + count);

二、内部类的种类

内部类可以分为四种:成员内部类、局部内部类、匿名内部类和静态内部类

Java程序员必备基础:内部类解析_匿名内部类_02

静态内部类

定义在类内部的静态类,就是静态内部类。

  1. public class Outer

  2. private static int radius = 1;

  3. static class StaticInner
  4. public void visit()
  5. System.out.println("visit outer static variable:" + radius);

静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量;静态内部类的创建方式, ​new外部类.静态内部类()​,如下:

  1. Outer.StaticInner inner = new Outer.StaticInner();
  2. inner.visit();

成员内部类

定义在类内部,成员位置上的非静态类,就是成员内部类。

  1. public class Outer

  2. private static int radius = 1;
  3. private int count =2;

  4. class Inner
  5. public void visit()
  6. System.out.println("visit outer static variable:" + radius);
  7. System.out.println("visit outer variable:" + count);

成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。成员内部类依赖于外部类的实例,它的创建方式 ​外部类实例.new内部类()​,如下:

  1. Outer outer = new Outer();
  2. Outer.Inner inner = outer.new Inner();
  3. inner.visit();

局部内部类

定义在方法中的内部类,就是局部内部类。

  1. public class Outer

  2. private int out_a = 1;
  3. private static int STATIC_b = 2;

  4. public void testFunctionClass()
  5. int inner_c =3;
  6. class Inner
  7. private void fun()
  8. System.out.println(out_a);
  9. System.out.println(STATIC_b);
  10. System.out.println(inner_c);
  11. Inner inner = new Inner();
  12. inner.fun();
  13. public static void testStaticFunctionClass()
  14. int d =3;
  15. class Inner
  16. private void fun()
  17. // System.out.println(out_a); 编译错误,定义在静态方法中的局部类不可以访问外部类的实例变量
  18. System.out.println(STATIC_b);
  19. System.out.println(d);
  20. Inner inner = new Inner();
  21. inner.fun();

定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。局部内部类的创建方式,在对应方法内, ​new内部类()​,如下:

  1. public static void testStaticFunctionClass()
  2. class Inner
  3. Inner inner = new Inner();

匿名内部类

匿名内部类就是没有名字的内部类,日常开发中使用的比较多。

  1. public class Outer

  2. private void test(final int i)
  3. new Service()
  4. public void method()
  5. for (int j = 0; j < i; j++)
  6. System.out.println("匿名内部类" );
  7. .method();
  8. //匿名内部类必须继承或实现一个已有的接口
  9. interface Service
  10. void method();

除了没有名字,匿名内部类还有以下特点:

  • 匿名内部类必须继承一个抽象类或者实现一个接口。
  • 匿名内部类不能定义任何静态成员和静态方法。
  • 当所在的方法的形参需要被匿名内部类使用时,必须声明为 final。
  • 匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

匿名内部类创建方式:

  1. new 类/接口
  2. //匿名内部类实现部分

三、内部类的优点

我们为什么要使用内部类呢?因为它有以下优点:

  • 一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
  • 内部类不为同一包的其他类所见,具有很好的封装性;
  • 内部类有效实现了“多重继承”,优化 java 单继承的缺陷。
  • 匿名内部类可以很方便的定义回调。

一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!

  1. public class Outer

  2. private int radius = 1;

  3. protected void test()
  4. System.out.println("我是外部类方法");

  5. class Inner
  6. public void visit()
  7. System.out.println("访问外部类变量" + radius);
  8. test();

我们可以看到,内部类Inner是可以访问外部类Outer的私有变量radius或者方法test的。

内部类不为同一包的其他类所见,具有很好的封装性

当内部类使用 private修饰时,这个类就对外隐藏了。当内部类实现某个接口,并且进行向上转型,对外部来说,接口的实现已经隐藏起来了,很好体现了封装性。

  1. //提供的接口
  2. interface IContent
  3. String getContents();

  4. public class Outer
  5. //私有内部类屏蔽实现细节
  6. private class PContents implements IContent
  7. @Override
  8. public String getContents()
  9. System.out.println("获取内部类内容");
  10. return "内部类内容";

  11. //对外提供方法
  12. public IContent getIContent()
  13. return new PContents();

  14. public static void main(String[] args)
  15. Outer outer=new Outer();
  16. IContent a1=outer.getIContent();
  17. a1.getContents();

我们可以发现,Outer外部类对外提供方法getIContent,用内部类实现细节,再用private修饰内部类,屏蔽起来,把Java的封装性表现的淋漓尽致。

内部类有效实现了“多重继承”,优化 java 单继承的缺陷。

我们知道Java世界中,一个类只能有一个直接父类,即以单继承方式存在。但是内部类让“多继承”成为可能:

  • 一般来说,内部类继承某个类或者实现某个接口,内部类的代码操作创建它的外围类的对象。内部类提供了某种进入其外围类的窗口。
  • 每个内部类都可以队里的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类没有影响
  • 接口解决了部分问题,一个类可以实现多个接口,内部类允许继承多个非接口类型(类或抽象类)。

一份来自Java编程思想,内部类实现“多继承”的温暖如下:

  1. java基础之内部类

    java基础15 内部类(成员内部类局部内部类)和匿名内部类

    Java基础之内部类

    Java——基础知识——内部类

    Java基础语法09-面向对象下-内部类

    Java基础之内部类