深入理解Java:内部类(4)

只需简单地传递合适的参数给基类的构造器即可,这里是将x 传进new Wrapping(x)。在匿名内部类末尾的分号,并不是用来标记此内部类结束(C++中是那样)。实际上,它标记的是表达式的结束,只不过这个表达式正巧包含了内部类罢了。因此,这与别的地方使用的分号是一致的。

如果在匿名类中定义成员变量或者使用带参数的构造函数,你同样能够对其执行初始化操作:

public class Parcel8 {
    // Argument must be final to use inside
    // anonymous inner class:
    public Destination dest(final String name, String city) {
        return new Destination(name, city) {
            private String label = name;

public String getName() {
                return label;
            }
        };
    }

public static void main(String[] args) {
        Parcel8 p = new Parcel8();
        Destination d = p.dest("Tanzania", "gz");
    }

abstract class Destination {
        Destination(String name, String city) {
            System.out.println(city);
        }

abstract String getName();
    }
}

注意这里的形参city,由于它没有被匿名内部类直接使用,而是被抽象类Inner的构造函数所使用,所以不必定义为final。

内部类的重载问题

如果你创建了一个内部类,然后继承其外围类并重新定义此内部类时,会发生什么呢?也就是说,内部类可以被重载吗?这看起来似乎是个很有用的点子,但是“重载”内部类就好像它是外围类的一个方法,其实并不起什么作用:

class Egg {
      private Yolk y;
 
      protected class Yolk {
              public Yolk() {
                    System.out.println("Egg.Yolk()");
              }
      }
 
      public Egg() {
              System.out.println("New Egg()");
              y = new Yolk();
      }
}
 
public class BigEgg extends Egg {
      public class Yolk {
              public Yolk() {
                    System.out.println("BigEgg.Yolk()");
              }
      }
 
      public static void main(String[] args) {
              new BigEgg();
      }
}

输出结果为:

New Egg()

Egg.Yolk()

缺省的构造器是编译器自动生成的,这里是调用基类的缺省构造器。你可能认为既然创建了BigEgg 的对象,那么所使用的应该是被“重载”过的Yolk,但你可以从输出中看到实际情况并不是这样的。

这个例子说明,当你继承了某个外围类的时候,内部类并没有发生什么特别神奇的变化。这两个内部类是完全独立的两个实体,各自在自己的命名空间内。当然,明确地继承某个内部类也是可以的:

class Egg2 {
      protected class Yolk {
              public Yolk() {
                    System.out.println("Egg2.Yolk()");
              }
 
              public void f() {
                    System.out.println("Egg2.Yolk.f()");
              }
      }
 
      private Yolk y = new Yolk();
 
      public Egg2() {
              System.out.println("New Egg2()");
      }
 
      public void insertYolk(Yolk yy) {
              y = yy;
      }
 
      public void g() {
              y.f();
      }
}
 
public class BigEgg2 extends Egg2 {
      public class Yolk extends Egg2.Yolk {
              public Yolk() {
                    System.out.println("BigEgg2.Yolk()");
              }
 
              public void f() {
                    System.out.println("BigEgg2.Yolk.f()");
              }
      }
 
      public BigEgg2() {
              insertYolk(new Yolk());
      }
 
      public static void main(String[] args) {
              Egg2 e2 = new BigEgg2();
              e2.g();
      }
}

输出结果为:

Egg2.Yolk()

New Egg2()

Egg2.Yolk()

BigEgg2.Yolk()

BigEgg2.Yolk.f()

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9ec0ab425816ec2063e8692dcaa2ca69.html