Java编程思想5

第十章:内部类
可以将一个类得定义放在另一个类得定义内部,这就是内部类。

链接到外部类
在最初,内部类看起来就像是一种代码隐藏机制;其实它还有其他用途。当生成一个内部类的对象时,此对象与制造它的外围对象之间就有了一种联系,所以它能访问其外围对象的所有成员,而不需要任何特殊条件。此外,内部类还拥有其外围类的所有元素的访问权。如下:

interface Selector {
// 检查元素是否到末尾
boolean end();
// 访问当前对象
Object current();
// 移动到序列中的下一个对象
void next();
}

public class Sequence {
private Object[] items;
private int next = 0;

public Sequence(int size) {
this.items = new Object[size];
}

public void add(Object o) {
if (next < items.length) {
items[next++] = o;
}
}

// 内部类可以访问外围类的方法和字段
private class SequenceSelector implements Selector {
private int i = 0;

@Override
public boolean end() {
// 内部类自动拥有对其外围类所有成员的访问权
return i == items.length;
}

@Override
public Object current() {
return items[i];
}

@Override
public void next() {
if (i < items.length) {
i++;
}
}
}

public Selector selector() {
return new SequenceSelector();
}

public static void main(String[] args) {
Sequence sequence = new Sequence(10);
for (int i = 0; i < 10; i++) {
sequence.add(Integer.toString(i));
}
Selector selector = sequence.selector();
while (!selector.end()) {
System.out.print(selector.current() + " ");
selector.next();
}
}
}

使用.this 和 .new

  1. 如果你需要生成对外部对象的引用,可以使用外部类的名字后面紧跟原点和this。这样产生的引用会自动地具有正确的类型,这一点在编译器就会被知晓并受到检查,因此没有任何运行时开销,如下:

public class DoThis {
void f() {
System.out.println("DoThis.f()");
}

public class Inner {
public DoThis outer() {
// 使用.this语法,生成外部类对象的引用
return DoThis.this;
}
}

public Inner inner(){
return new Inner();
}

public static void main(String[] args) {
DoThis dt = new DoThis();
Inner inner = dt.inner();
inner.outer().f();
}
}

有时你可能想要告知某些其他对象,去创建某个内部类的对象,你必须在new表达式中提供对外部类对象的引用,这时需要使用.new语法,如下:

public class DotNew {

public class Inner {}

public static void main(String[] args) {
DotNew dotNew = new DotNew();
// 使用.new 语法生成内部类的对象
Inner inner = dotNew.new Inner();
}
}在拥有外部类对象之前是不可能创建内部类对象的。这是因为内部类对象会暗暗地连接到创建到它的外部类对象上。但是,如果你创建的时嵌套类(静态内部类),那么他就不需要对外部类对象的引用。如下:

public class Parcel3 {
// 静态内部类
static class Contents {
private int i = 11;
public int value() {
return i;
}
}

public static void main(String[] args) {
Parcel3.Contents contents = new Parcel3.Contents();
System.out.println(contents.value());
}

}

 

posted @   就叫清风吧  阅读(43)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示