如何创建内部类
- 如何在外部类的非静态成员方法中创建?
- 如何在除 1 条件下中使用内部类,如 main 函数
%
- 外部类
//: innerclasses/Parcel1.java
package innerclasses; /* Added by Eclipse.py */
// Creating inner classes.
public class Parcel1 {
class Contents {
private int i = 11;
public int value() { return i; }
}
class Destination {
private String label;
Destination(String whereTo) {
label = whereTo;
}
String readLabel() { return label; }
}
// Using inner classes looks just like
// using any other class, within Parcel1:
// 创建内部类
public void ship(String dest) {
Contents c = new Contents();
Destination d = new Destination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args) {
Parcel1 p = new Parcel1();
p.ship("Tasmania");
}
} /* Output:
Tasmania
*///:~
- 其他位置
从非外部类的的非成员方法中使用内部类
必须指名内部类的对象格式:OuterClassName.InnerClassName
//: innerclasses/Parcel2.java
package innerclasses; /* Added by Eclipse.py */
// Returning a reference to an inner class.
public class Parcel2 {
class Contents {
private int i = 11;
public int value() { return i; }
}
class Destination {
private String label;
Destination(String whereTo) {
label = whereTo;
}
String readLabel() { return label; }
}
public Destination to(String s) {
return new Destination(s);
}
public Contents contents() {
return new Contents();
}
public void ship(String dest) {
Contents c = contents();
Destination d = to(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args) {
Parcel2 p = new Parcel2();
p.ship("Tasmania");
Parcel2 q = new Parcel2();
// Defining references to inner classes:
// 使用
Parcel2.Contents c = q.contents();
Parcel2.Destination d = q.to("Borneo");
}
} /* Output:
Tasmania
*///:~
如何链接到外部类
内部类如何调用外部类成员和方法
%
无需操心,自动有外部类对象的引用
//: innerclasses/Sequence.java
package innerclasses; /* Added by Eclipse.py */
// Holds a sequence of Objects.
interface Selector {
boolean end();
Object current();
void next();
}
public class Sequence {
private Object[] items;
private int next = 0;
public Sequence(int size) { items = new Object[size]; }
public void add(Object x) {
if(next < items.length)
items[next++] = x;
}
private class SequenceSelector implements Selector {
private int i = 0;
public boolean end() { return i == items.length; }
public Object current() { return items[i]; }
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();
}
}
} /* Output:
0 1 2 3 4 5 6 7 8 9
*///:~
何时使用.this 和.new
%
- 内部类想返回当前外部类的引用时返回.this
//: innerclasses/DotThis.java
package innerclasses; /* Added by Eclipse.py */
// Qualifying access to the outer-class object.
public class DotThis {
void f() { System.out.println("DotThis.f()"); }
public class Inner {
public DotThis outer() {
return DotThis.this;
// A plain "this" would be Inner's "this"
}
}
public Inner inner() { return new Inner(); }
public static void main(String[] args) {
DotThis dt = new DotThis();
DotThis.Inner dti = dt.inner();
dti.outer().f();
}
} /* Output:
DotThis.f()
*///:~
- 其他对象想创建内部类的时候,使用.new
- 此处不用也不能使用 dn.new DotNew.Inner();
- 在拥有外部类对象之前是不可能创造内部对象的,除非创建的是嵌套类(静态内部类)
//: innerclasses/DotNew.java
package innerclasses; /* Added by Eclipse.py */
// Creating an inner class directly using the .new syntax.
public class DotNew {
public class Inner {}
public static void main(String[] args) {
DotNew dn = new DotNew();
DotNew.Inner dni = dn.new Inner();
}
} ///:~
内部类的向上转型有什么作用
%
如果把内部类设置成 private、protected 可以很好的隐藏接口实现的细节
接口代码
public interface Destination {
String readLabel();
} ///:~
public interface Contents {
int value();
} ///:~
向上转型的内部类的使用
//: innerclasses/TestParcel.java
package innerclasses; /* Added by Eclipse.py */
class Parcel4 {
private class PContents implements Contents {
private int i = 11;
public int value() { return i; }
}
protected class PDestination implements Destination {
private String label;
private PDestination(String whereTo) {
label = whereTo;
}
public String readLabel() { return label; }
}
public Destination destination(String s) {
return new PDestination(s);
}
public Contents contents() {
return new PContents();
}
}
public class TestParcel {
public static void main(String[] args) {
Parcel4 p = new Parcel4();
Contents c = p.contents();
Destination d = p.destination("Tasmania");
// Illegal -- can't access private class:
//! Parcel4.PContents pc = p.new PContents();
}
} ///:~
如何创建和初始化匿名类
%
- 使用父类方法构造匿名类
public class Parcel8 {
public Wrapping wrapping(int x) {
// Base constructor call:
return new Wrapping(x) { // Pass constructor argument.
public int value() {
return super.value() * 47;
}
}; // Semicolon required
}
public static void main(String[] args) {
Parcel8 p = new Parcel8();
Wrapping w = p.wrapping(10);
}
} ///:~
- 初始化方法构建匿名类的构造
因为匿名类没名字不可能有构造方法,所以使用初始化的方法模拟
因为匿名类的初始化相当于使用外部的数据,要用 final 类型的数据
public class Parcel10 {
public Destination
destination(final String dest, final float price) {
return new Destination() {
private int cost;
// Instance initialization for each object:
{
cost = Math.round(price);
if(cost > 100)
System.out.println("Over budget!");
}
private String label = dest;
public String readLabel() { return label; }
};
}
public static void main(String[] args) {
Parcel10 p = new Parcel10();
Destination d = p.destination("Tasmania", 101.395F);
}
} /* Output:
Over budget!
*///:~