嵌套类分为四种:

  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. 什么时候必须使用UI相机? 多个相机的作用原理?

    首先,要从主画布说起,maincanvas,这个有什么限制?主画布是一张默认用来绘制UI的地方,这些UI必须是系统提供的UI组件,在画面下挂一个3D物体或非UI的2D物品是不会被绘制到画布上的,但是仍 ...

  2. python操作符重载

    操作符重载的魔术方法 操作符 方法 取反 即席 + __add__ __radd__ __iadd__ - __sub__ __rsub__ __isub__ * __mul__ __rmul__ _ ...

  3. 读书笔记 Week7 2018-4-24

    <程序员的自我修养> 首先来大致说一下读这本书的感觉,可以说对于我自己而言,是第一次对于编程有了个纯粹的认识,或者说的更明确一点,是对整个操作系统有了一个大致的感觉.虽然自己这一年也算是写 ...

  4. 06.Lucen入门程序-Field

    需求: 实现一个歌词搜索系统,通过关键字搜索,凡是文件名或文件内容包括关键字的文件都要找出来. 注意:该入门程序只对文本文件(.txt)搜索. Lucene中包含两个重要的类: IndexWriter ...

  5. vue和bootstrap的select控件貌似有冲突?

    貌似vue和bootstrap的select控件会冲突,因为bootstrap的select控件会将option替换为<a>标签,这样就会导致vue渲染失败.(这个问题让我整了一个上午,最 ...

  6. windows版本免安装redis, nginx, zookeeper

    redis官网:https://redis.io/ windows版本免安装redis下载链接:https://github.com/MSOpenTech/redis/releases nginx官网 ...

  7. linux系统如何更改文件权限

    一. 更改文件9个属性:chmod 用这个命令修改文件属性有两种方式:数字或者符号 1. 数字类型改变文件权限 chmod (1)类unix系统的文件有9个属性分别是owner/group/other ...

  8. Python学习笔记_读Excel去重

    读取一个Excel文件,按照某列关键字,如果有重复则去掉 这里不介绍所有的解决办法,只是列出一个办法. 软件环境: OS:Win10 64位 Python 3.7 测试路径:D:\Work\Pytho ...

  9. SQL 数据库 学习 006 如何设置一个用户名和密码

    我的电脑系统: Windows 10 64位 使用的SQL Server软件: SQL Server 2014 Express 先启动 SQL Server 2014 Management Studi ...

  10. Openssl errstr命令

    一.简介 errstr命令用于查询错误代码 二.语法 errstr [-stats] <errno> 选项 -stats:打印哈希表状态 errno:错误号 三.实例 1.查看错误信息 : ...