嵌套类分为四种:

  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 {}

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

《Beginning Java 7》 - 9 - Nested Types 嵌套类型的更多相关文章

  1. Java中的Nested Classes和Inner Classes

    Java中的Nested Classes和Inner Classes Java有嵌套类(Nested Classes)和内部类(Inner Classes)的概念. 嵌套类(Nested Classe ...

  2. 细述 Java垃圾回收机制→Types of Java Garbage Collectors

    细述 Java垃圾回收机制→Types of Java Garbage Collectors 转自:https://segmentfault.com/a/1190000006214497 本文非原创, ...

  3. swift 20 - Nested Types

    Nested Types 只是为了方便类型的整合和使用 struct BlackjackCard { // nested Suit enumeration enum Suit: Character { ...

  4. JSON parse error: default constructor not found. class java.time.YearMonth; nested exception is com.alibaba.fastjson.JSONException: default constructor not found. class java.time.YearMonth

    java8新出的YearMonth可以方便的用来表示某个月.我的项目中使用springmvc来接收YearMonth类型的数据时发现 x-www-from-urlencoded 格式的数据可以使用&q ...

  5. Effective Java 26 Favor generic types

    Use generic types to replace the object declaration Add one or more type parameters to its declarati ...

  6. Java Inner class && nested class

    Java中,Inner Class(不被 static修饰)可以访问outer class 的所有成员(包括私有成员),同时,内部类 的创建必须经由外部类的实例! nested class 有stat ...

  7. Welcome-to-Swift-19类型嵌套(Nested Types)

    枚举类型常被用于实现特定类或结构体的功能.也能够在有多种变量类型的环境中,方便地定义通用类或结构体来使用,为了实现这种功能,Swift允许你定义类型嵌套,可以在枚举类型.类和结构体中定义支持嵌套的类型 ...

  8. Effective Java 49 Prefer primitive types to boxed primitives

    No. Primitives Boxed Primitives 1 Have their own values Have identities distinct from their values 2 ...

  9. Java中的Union Types和Intersection Types

    前言 Union Type和Intersection Type都是将多个类型结合起来的一个等价的"类型",它们并非是实际存在的类型. Union Type Union type(联 ...

随机推荐

  1. IDEA2017 破解方式

    1. 到网站 http://idea.lanyus.com/ 获取注册码. 2.填入下面的license server: http://intellij.mandroid.cn/ http://ide ...

  2. Spring <context:annotation-config />讲解

    在基于主机方式配置Spring的配置文件中,你可能会见到<context:annotation-config />这样一条配置,他的作用是向Spring容器注册AutowiredAnnot ...

  3. DEV 打印功能

    Dev13.1 用的是DocumentViewer,上面的一排按钮,是自动生成的,生成方法为:加了DocumentViewer后,控件右上角有个小三角,点一下,在弹出框中选择"Create ...

  4. 3D Math Keynote

    [3DMathKeynote] 1.常用公式. 1)(A*B)^T = B^T*A^T.   2)(A*B)^-1 = B^-1*A^-1. 3)|A*B| = |A|*|B|. 4)|M^T|=|M ...

  5. IDEA05 mybatis插件之MyBatisCodeHelper-Pro

    前提准备: >IDEA专业版本 1 安装MyBatisCodeHelper-Pro IDEA提供了插件安装功能,可以根据开发需要安装适合的插件 >help -> find actio ...

  6. 如何申请新浪SAE,发布自己的网站

    你是否会看见诸如(***.sinaapp.com)类的域名?是否和新浪有什么关系?抑或想要一个免费的空间展示自己的个人主页;没问题,下面我来分享一下SAE的申请流程吧! 首先,打开SAE(http:/ ...

  7. [Training Video - 3] [Groovy in Detail] What is a groovy class ?

    log.info "starting" // we use class to create objects of a class Planet p1 = new Planet() ...

  8. 一起做RGB-D SLAM (4)

    第四讲 点云拼接 广告:“一起做”系列的代码网址:https://github.com/gaoxiang12/rgbd-slam-tutorial-gx 当博客更新时代码也会随着更新. SLAM技术交 ...

  9. JS实现windows.open打开窗口并居中

    function openWin() {            var url='Add.aspx';                             //转向网页的地址;           ...

  10. Qcreator3.1.2调试器(windows)版本

    环境:visual studio 2012 qt:5.3.1 默认的ms版本qtcreator只能使用visual studio的编译器,不能使用调试工具.需要gdb或者cdb进行调试,这里介绍使用的 ...