1、内部类的形式:
在Thinking in java中有parcel的例子,里面包含两个内部类,Contents和Destination。然后在parcel类的ship()函数内构建两个内部类的引用。可以通过这两个内部类的对象调用对象方法。也可以在外部类parcel里建立方法,该方法返回内部类的对象。那么,在构建外部类的对象后可以调用该方法新建内部类对象。
Eg:
package oop;
public class Pacel2 {
class Content{
private int i;
public int value(){
return i;
}
}
class Destination{
private String label;
private Destination(String whereTo){
this.label = whereTo;
}
private String readLabel(){
return label;
}
}
public Destination to(String s){
return new Destination(s);
}
public Content content(){
return new Content();
}
public void ship(String dest){
Content c = new Content();
Destination d = new Destination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args){
Pacel2 p = new Pacel2();
p.ship("杨婷婷");
Pacel2 q = new Pacel2();
Pacel2.Content c = q.content();
Pacel2.Destination d = q.to("好姑娘");
}
}
2、为什么要用内部类?
内部类产生对象必须有一个重要的前提条件,那就是它的外部类对象必须先创建,通过外部类的对象构建内部类对象,有两种方法:其中之一就向上面那样,外部类有一个public方法生产内部类的对象;其二是通过外部类对象实现。
[java] view plain copy
Parcel2.Contents c = q.new Contents();
这要求内部类Inner是public或者protected访问权限。内部类的另一个重要特性是:它可以不受限制的访问其所在外部类的域。java可以实现多个接口,implements inerfaceA, interfaceB。但是不允许多重继承类,如果你确实需要利用例外的类来操控本类的成员,可以利用内部类满足这个需要。
3、利用内部类可以方便实现哪些功能?
无论是方法内部类还是匿名内部类,它们的共同点同2中提到的一样,可以不受限制的访问外部类的域和方法。同时,可根据限制条件让内部类隐藏或向上转型为接口类型,从而消除方法返回的具体类型的限制。匿名内部类可以隐藏接口的具体实现,使得类的使用者只关注要实现的目标。
Eg:
public interface inner {
int fi();
}
package oop;
public class Out {
private int i;
private int f(){
return i;
}
public Out(int i){
this.i = i;
}
public inner cf(){
return new inner(){
@Override
public int fi() {
i++;
return f();
}
};
}
public static void main(String[] args){
Out out = new Out(4);
inner oi = out.cf();
System.out.println("this i = " + oi.fi());
}
}
从这个例子可以看到接口inner是以匿名内部类的方式实现的。在外部类out中,定义一个函数cf(),该函数返回接口inner,在函数内部实现接口并实例化。可以看到,匿名内部类有普通内部类一样的重要特性,那就是可以不受限制的访问外部类的域和方法。
4、内部类的实现机制?
5、内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?
非静态内部类可以访问外部类的一切属性和方法,静态内部类不可以在普通方法和静态方法里访问外部类的实例成员。
二、程序题
1、A:成员内部类:
public interface Instrument {
public void play();
}
package oop;
public class InstrumentTest {
public static class Instrument1 implements Instrument{
@Override
public void play() {
System.out.println("开始演奏");
}
}
public void playInstrument(Instrument ins){
ins.play();
}
public static void main(String[] args){
InstrumentTest i = new InstrumentTest();
i.playInstrument(new Instrument1());
}
}
B、局部内部类:
package oop;
public class InstrumentTest01 {
public void playStrument(){
class Instrument1 implements Instrument{
@Override
public void play() {
System.out.println("开始演奏...");
}
}
new Instrument1().play();
}
public static void main(String[] args){
InstrumentTest01 i = new InstrumentTest01();
i.playStrument();
}
}
C:匿名类
package oop;
public class InstrumentTest02 {
public void palyStrument(){
new Instrument(){
@Override
public void play() {
System.out.println("开始演奏啊");
}
}.play();
}
public static void main(String[] args) {
InstrumentTest02 i = new InstrumentTest02();
i.palyStrument();
}
}
2、Father类:
public class Father {
private String name = "zhangjun";
class Child{
public void introFather(){
System.out.println("my father name is:" + name);
}
}
}
测试类:
public static void main(String[] args) {
Father.Child child = new Father().new Child();
child.introFather();
}