`
iwindyforest
  • 浏览: 230702 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

内部类学习笔记

阅读更多
Inner Classes
创建
If an inner class has constructors, the compiler modifies them, adding a parameter for the outer class reference.
如果一个内部类没有构造函数, 编译器会改变它们, 加上一个外部类的引用作为参数.
Conversely, you can write the inner object constructor more explicitly, using the syntax
outerObject.new InnerClass(construction parameters)
For example,
ActionListener listener = this.new TimePrinter();
相反的, 你可以用更加显式的方法写内部类的构造函数, 语法是:
outerObject.new InnerClass(construction parameters)
例如:
ActionListener listener = this.new TimePrinter();

外部类的访问
In the preceding section, we explained the outer class reference of an inner class by calling it outer. Actually, the proper syntax for the outer reference is a bit more complex. The expression
OuterClass.this
外部类的访问语法为: OuterClass.this

内部类的访问
Note that you refer to an inner class as:

OuterClass.InnerClass
注意引用内部类的方法是: OuterClass.InnerClass
Local Inner Classes
局部内部类
定义在函数内部的内部类为局部内部类
public void start()
{
   class TimePrinter implements ActionListener
   {
      public void actionPerformed(ActionEvent event)
      {
          Date now = new Date();
          System.out.println("At the tone, the time is " + now);
          if (beep) Toolkit.getDefaultToolkit().beep();
      }
   }

   ActionListener listener = new TimePrinter();
   Timer t = new Timer(1000, listener);
   t.start();
}
Local classes are never declared with an access specifier (that is, public or private). Their scope is always restricted to the block in which they are declared.
局部类不能以任一访问修饰符修饰. 它们的范围被限定在定义它的语句块内部.

Local classes have a great advantage: they are completely hidden from the outside world—not even other code in the TalkingClock class can access them. No method except start has any knowledge of the TimePrinter class.
局部类有一个非常大的优点: 他们对于外部世界完全隐藏, 甚至TalkingClock类内部的其余代码也不能访问他们. 除start()函数外的其余方法都不能获悉TimerPrinter局部类的访问.

Anonymous Inner Classes
匿名内部类
Any parameters used to construct the object are given inside the parentheses ( ) following the supertype name. In general, the syntax is

new SuperType(construction parameters)
{
   inner class methods and data
}
Here, SuperType can be an interface, such as ActionListener; then, the inner class implements that interface. Or SuperType can be a class; then, the inner class extends that class.
父类构造函数的内部可以使用任意的参数. 一般来说, 语法为:
new SuperType(construction parameters)
{
   inner class methods and data
}
这里, SuperType可以为接口, 比如ActionListener; 那么, 内部类将会实现此接口. 或者为一个类; 那么这个内部类将继承此类.
An anonymous inner class cannot have constructors because the name of a constructor must be the same as the name of a class, and the class has no name. Instead, the construction parameters are given to the superclass constructor. In particular, whenever an inner class implements an interface, it cannot have any construction parameters. Nevertheless, you must supply a set of parentheses as in
一个匿名内部类不能有多个构造函数, 因为构造函数必须同名函数, 但是匿名内部类是没有类名的. 取而代之的是, 匿名内部类的构造函数参数将会给予超类的构造函数. 特别的是, 无论什么时候一个匿名内部类实现接口都不能有任何带参数的构造函数. 然而, 你必须在其内部提供一系列数据.
Static Inner Classes
静态内部类
Occasionally, you want to use an inner class simply to hide one class inside another, but you don't need the inner class to have a reference to the outer class object. You can suppress the generation of that reference by declaring the inner class static.
有时候, 你想用一个内部类只是为了在另一个类中隐藏它, 但是你不需要这个内部类 访问外部类的索引. 你可以声明此内部类为静态的来一只外部类索引的生成.
Here is a typical example of where you would want to do this. Consider the task of computing the minimum and maximum value in an array. Of course, you write one method to compute the minimum and another method to compute the maximum. When you call both methods, then the array is traversed twice. It would be more efficient to traverse the array only once, computing both the minimum and the maximum simultaneously.
这里有一个典型的例子. 设想计算一个数组的最大最小值. 当然, 你写了一个方法去计算最小值, 另一计算最大值. 当你调用这两个方法是, 这个数字会遍历两次. 只遍历数字一次就同时取得数组的最大最小值的算法是更有效率的.
double min = Double.MAX_VALUE;
double max = Double.MIN_VALUE;
for (double v : values)
{
   if (min > v) min = v;
   if (max < v) max = v;
}

However, the method must return two numbers. We can achieve that by defining a class Pair that holds two values:
尽管如此, 这个方法必须返回两个值. 我们可以定义一个Pair类来实现保存这两个值.
class Pair
{
   public Pair(double f, double s)
   {
      first = f;
      second = s;
   }
   public double getFirst() { return first; }
   public double getSecond() {  return second; }

   private double first;
   private double second;
}

The minmax function can then return an object of type Pair.
那么minmax()函数就能够返回一个Pair类型的对象了.
class ArrayAlg
{
   public static Pair minmax(double[] values)
   {
      . . .
      return new Pair(min, max);
   }
}

The caller of the function uses the getFirst and getSecond methods to retrieve the answers:
这个函数的调用者使用Pair类的getFirst()和getSecond()函数来返回结果.
Pair p = ArrayAlg.minmax(d);
System.out.println("min = " + p.getFirst());
System.out.println("max = " + p.getSecond());

Of course, the name Pair is an exceedingly common name, and in a large project, it is quite possible that some other programmer had the same bright idea, except that the other programmer made a Pair class that contains a pair of strings. We can solve this potential name clash by making Pair a public inner class inside ArrayAlg. Then the class will be known to the public as ArrayAlg.Pair:
当然, Pair类名是一个非常常见的名字, 在一个大项目中, 很可能其他程序员有着相同的注意. 我们可以通过吧Pair声明为public来解决这个潜在的问题. 那么这个类将会以: ArrayAlg.Pair来访问.
ArrayAlg.Pair p = ArrayAlg.minmax(d);

However, unlike the inner classes that we used in previous examples, we do not want to have a reference to any other object inside a Pair object. That reference can be suppressed by declaring the inner class static:
尽管如此, 不像我们以前例子中用到的内部类, 我们不想再Pair类中拥有任何其它类的引用, 因此将这个内部类声明为static可以抑制索引的生成.
class ArrayAlg
{
   public static class Pair
   {
      . . .
   }
   . . .
}

Of course, only inner classes can be declared static. A static inner class is exactly like any other inner class, except that an object of a static inner class does not have a reference to the outer class object that generated it. In our example, we must use a static inner class because the inner class object is constructed inside a static method:
当然, 只有静态内部类可以被声明为static. 一个静态内部类出来不含其它类的引用之外同其他类型的内部类没有区别.在我们的例子中, 我们必须使用静态内部类, 因为它被用在了静态方法中.
public static Pair minmax(double[] d)
{
    . . .
    return new Pair(min, max);
}

Had the Pair class not been declared as static, the compiler would have complained that there was no implicit object of type ArrayAlg available to initialize the inner class object.
如果Pair类没有被声明为静态的, 那么编译器便会报告没有显示可以的静态内部类初始化对象.
NOTE
You use a static inner class whenever the inner class does not need to access an outer class object. Some programmers use the term nested class to describe static inner classes.
当一个内部类不需要访问任何外部对象时你需要声明此类为静态内部类. 有些程序员使用终端嵌套类去描述静态内部类.
Inner classes that are declared inside an interface are automatically static and public.
定义在一个接口中的静态类会被自动声明为static和public.
2
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics