嵌套类分为四种:

  1. static member class 静态成员类
  2. nonstatic member class 非静态成员类
  3. anonymous class 匿名类
  4. local class 局部类

后三者统称为 inner class 内部类。

还有一种嵌套的形式叫 interfaces within classes 类内部接口,我们在最后介绍。

1. Static Member Class 静态成员类

//外围类
class EnclosingClass{
  private static int i; //私有静态属性
  //私有静态方法 m1
  private static void m1(){
    System.out.println(i);
  }
  //私有静态方法 m2,调用嵌套类里面的静态方法
  static void m2(){
    EnclosedClass.accessEnclosingClass();
  }
  //静态成员类
  static class EnclosedClass{
    //静态方法,调用外围类的静态方法和静态属性
    static void accessEnclosingClass(){
      i = 1;
      m1();
    }
    //非静态方法,调用外围类的静态方法
    void accessEnclosingClass2(){
      m2();
    }
  }
}

主函数:

class SMCDemo { 
  public static void main(String[] args) { 
    EnclosingClass.EnclosedClass.accessEnclosingClass(); // Output: 1       EnclosingClass.EnclosedClass ec = new EnclosingClass.EnclosedClass();     ec.accessEnclosingClass2(); // Output: 1
  }}

简单总结:

  • 外部类不可以是 static 的,所以静态的非嵌套类不存在。
  • 静态成员类跟静态方法一样,只能访问静态的成员变量和方法,不能访问非静态的方法和属性,但是普通内部类可以访问任意外部类的成员变量和方法。
  • 静态成员类可以声明普通成员变量和方法,而内部类不能声明static成员变量和方法。
  • 静态成员类可以直接实例化,不需要实例化外部类。比如 new Outer.Inner(); 但内部类需要外部类的实例。

2. Nonstatic Member Class 非静态成员类

非静态成员类是内部类的最普通的形式。

class EnclosingClass{
  private int i;
  private void m(){
    System.out.println(i);
  }
  class EnclosedClass{
    void accessEnclosingClass(){
      i = 1;
      m();
    }
  }
}

主函数:

class NSMCDemo{
  public static void main(String[] args){
  EnclosingClass ec = new EnclosingClass();
  ec.new EnclosedClass().accessEnclosingClass(); // Output: 1
  }
}

用 ec.new EnclosedClass() 这样的方法来创建非静态成员类对象并不常用。常用的情况是在外围类中结构体中或非静态方法中来调用此非静态成员类的构造方法。

非静态成员类可以访问外围类的静态和非静态属性和方法。

3. Anonymous Class 匿名类

匿名类是一个没有名字的类。理论上它属于一个非静态的内部类。需要注意:

new Thread(new Runnable(){  public void run(){
  }}
).start();

这里面的 Thread 部分可不是一个匿名类,它是一个 unreferenced object。而 Runnable 部分是。

匿名类的基本语法是:

new InterfaceName(){......}; 
//或者
new SuperclassName(){......};

匿名类的特点和作用:

  • 匿名类是一个继承某个类的子类或者一个接口的实现。
  • 匿名类在声明的同时创建一个此类的实例。
  • 匿名类常用于创建细小的类。比如匿名类继承一个汽车类,我们就可以创建非常多不同的汽车的子类而不必须去为每种汽车起名字(当然这可能不是一个非常理想的例子)。匿名类好处是定制化,可以自由的实现,而且不用去创建太多的小类而使得程序变得复杂难懂。
  • 匿名类没有构造函数,它调用父类(继承的时候)的构造方法。
  • 匿名类只能调用 final 的变量或参数。

4. Local Class 局部类

一个局部类可以在任何一个声明局部变量的地方被声明,它的作用域相当于一个局部变量。和匿名类的区别在于,它有名字,它也可以被重用。

局部类的实例只可以访问外围作用域的 final 的属性和参数。

class EnclosingClass{
  void m(final int x){
    final int y = x*2;
    class LocalClass{
      int a = x;
      int b = y;
    }
    LocalClass lc = new LocalClass();
    System.out.println(lc.a);
    System.out.println(lc.b);
  }
}

局部类让程序更清晰。局部类的一个有趣的例子见书中142页。

Interfaces Within Classes 类内部接口

class X{
  interface A{
  }
  static interface B{
  }
}

类内部接口不管是否声明为 static,默认都是 static 的。用法:

class C implements X.A {}
//或者
class D implements X.B {}

接口内部嵌套接口是应该避免的,我们以后会讨论这个问题。

最新文章

  1. 第54课 Qt 中的多页面切换组件
  2. JavaScript中的防篡改对象
  3. linux Ubuntu(Segmentation fault)段错误出现原因及调试方法
  4. 网页中的CSS换行控制
  5. 安装交叉编译arm-linux-gcc环境
  6. CFUUIDRef和CFStringRef-生成唯一标识符
  7. Improving the AbiWord's Piece Table
  8. 饿了么移动APP的架构演进(转)
  9. ajax2016/4/15 post与get
  10. IP协议详解(转)
  11. Design5:SQL Server 文件和文件组
  12. 联发科AIoT平台i500处理器简介
  13. How to split DMG on macOS
  14. iOS必学技-cocoapods
  15. 多个桌面Deskspace如何使用
  16. Nodejs Web模块( readFile 根据请求跳转到响应html )
  17. 20145324 Java实验三
  18. Hadoop源码分析之客户端向HDFS写数据
  19. (转)nmon和nmon analyser的下载和使用
  20. [国家集训队]部落战争 最大流 BZOJ2150

热门文章

  1. Elasticsearch-PHP 概述
  2. SQL 组内排序
  3. MySQL数据库篇之索引原理与慢查询优化之二
  4. MongoDB动态条件之分页查询
  5. GetHashCode()
  6. Spring Data JPA动态查询(多条件and)
  7. Opencv读取图片像素值
  8. ATM取款机的数据库模拟开发和实战总结
  9. Red Hat Cluster Suite 组件 fencing FAQ
  10. 相机IMU融合四部曲(一):D-LG-EKF详细解读