《Beginning Java 7》 - 9 - Nested Types 嵌套类型
嵌套类分为四种:
- static member class 静态成员类
- nonstatic member class 非静态成员类
- anonymous class 匿名类
- 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 嵌套类型的更多相关文章
- Java中的Nested Classes和Inner Classes
Java中的Nested Classes和Inner Classes Java有嵌套类(Nested Classes)和内部类(Inner Classes)的概念. 嵌套类(Nested Classe ...
- 细述 Java垃圾回收机制→Types of Java Garbage Collectors
细述 Java垃圾回收机制→Types of Java Garbage Collectors 转自:https://segmentfault.com/a/1190000006214497 本文非原创, ...
- swift 20 - Nested Types
Nested Types 只是为了方便类型的整合和使用 struct BlackjackCard { // nested Suit enumeration enum Suit: Character { ...
- 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 ...
- Effective Java 26 Favor generic types
Use generic types to replace the object declaration Add one or more type parameters to its declarati ...
- Java Inner class && nested class
Java中,Inner Class(不被 static修饰)可以访问outer class 的所有成员(包括私有成员),同时,内部类 的创建必须经由外部类的实例! nested class 有stat ...
- Welcome-to-Swift-19类型嵌套(Nested Types)
枚举类型常被用于实现特定类或结构体的功能.也能够在有多种变量类型的环境中,方便地定义通用类或结构体来使用,为了实现这种功能,Swift允许你定义类型嵌套,可以在枚举类型.类和结构体中定义支持嵌套的类型 ...
- 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 ...
- Java中的Union Types和Intersection Types
前言 Union Type和Intersection Type都是将多个类型结合起来的一个等价的"类型",它们并非是实际存在的类型. Union Type Union type(联 ...
随机推荐
- 我的MAXSCRIPT笔记
getnodebyname "circle01" for o in objects do if o.name == "circle01" then select ...
- windows下python安装Numpy和Scipy模块
安装 numpy: 去 http://sourceforge.net/projects/numpy/files/latest/download?source=files 下载相应的exe安装文件. 安 ...
- space defender,太空版植物大战僵尸 游戏基本框架的设计
- out.write(b,0,len)怎么解释?
参数 缓冲区——要写的数据 从——开始偏移量数据 len——写的字节数 返回值 这个方法不返回一个值. 异常 IOException
- 为什么3D模型的网格由很多三角形来组成
因为二点确定一条线,三点确定一个面 网格就是由很多面组成的,四个点也能组成面 但是三个点就足够了
- Linux下安装Nginx详细图解教程(一)
什么是Nginx? Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器,在高连接并发的情况下N ...
- 面向对象的JavaScript-007-Function.prototype.bind() 的4种作用
1. // Function.prototype.bind() 的作用 // 1.Creating a bound function this.x = 9; var module = { x: 81, ...
- Openssl pkey命令
一.简介 pkey是一个公钥或私钥的处理命令,可以用于打印和转换不同的表单和组件 二.语法 openssl pkey [-inform PEM|DER] [-outform PE|DER] [-in ...
- tp5 sql 大于小于
1.大于 $rwhere['ctime'] = array('egt',10000); 2.小于 $rwhere[);
- [Training Video - 4] [Groovy] Optional parameter in groovy
Employee.log=log Employee e1 = new Employee() log.info e1.add(1,2,3,4) // optional parameters in gro ...