Java中的嵌入类

转载请标明出处: http://blog.csdn.net/zhangxingping

Java中的嵌入类(Nested Class)

嵌入类

Java编程语言中允许在一个类中定义另外的类。这个“另外”的类被称为是嵌入类。如下示例:

class OuterClass{
    …
    class NestedClass {
        …
    }
}

术语:嵌入类分为两种:静态(static)的和非静态(Non-static)的。静态的嵌入类被简单地称为“静态嵌入类”。非静态的嵌入类则被称为是内部类(Inner class).

class OuterClass{
    …
    static class StaticNestedClass {
        …
    }
    class InnerClass {
        …
    }
}

一个嵌入类是包含它的类的一个成员。非静态的嵌入类(内部类)是可以访问包含它的类的其他成员的,即便这些成员可能是私有的(private)。而静态的嵌入类是不能访问包含它的类的其他成员的。作为包含它的类的一个成员,嵌入类可以是私有的(private),公有的(public),受保护的(protected),或者是包类私有的(package private)。(会议一下,外面的类只能是公有的(public) 或者是包类私有(package private)。)

为什么要使用嵌入类?

有几种情况需要使用到嵌入类,其中:

  •  这是对只在一个地方使用的那些类进行分组的一种方式。
  •  嵌入类增强了代码的封装性。
  •  使用嵌入类可增加代码的可读性和可维护性。

对类进行逻辑分组——如果一个类在在另外一个中才有用,那么将其嵌入到这个另外的类中既可以保持他们在逻辑上是相关的,也可以保持他们在代码上是放在一起的。将这种辅助类嵌入到该类中也会使得整个包更合理。

增强封装性——考虑两个顶级的类A和B,假设B需要访问A中的某些成员,那么这些成员就必须被声明为公有的(public)。但是由于只有B才会访问这些成员,也就是说除了B不允许其他类访问这些成员,因此本来这些成员可以使私有的,仅仅是由于B的原因,我们不得不把这些成员声明为公有的。此时,使用内部类将B类嵌入到A类中,那么B这些成员就可以被声明为私有的,并且B类也是可以访问到这些成员的。另外,类B本身对于外界来说也就被隐藏起来了。

增强代码的可读性和可维护性——将小类嵌入到顶级类中,使得这些类的代码就和使用它们的代码放在了一起。

静态嵌入方法

与方法以及变量是和类相关的一样,一个静态嵌入类是和包含它的“外部”类是相关的。和静态类方法一样,静态的嵌入类是不能直接包含它的类的实例变量和方法的——他只能通过对象引用这些变量和方法。

注意: 静态潜入类是可以和其他的顶级类一样,可以与其外部类以及别的类进行交互的。实际上,静态类在行为上就是一个被嵌入到别的类当中的顶级类,这样做是为了打包方便。

静态嵌入类的使用是需要使用到他的“外部”类的名称的:

OuterClass.StaticNestedClass

例如,想要创建一个静态嵌入类的对象,可以使用如下的语句:

OuterClass.StaticNestedClassnestedObject =

    new OuterClass.StaticNestedClass();

内部类

与方法和变量是和类的实例相关的一样,内部类也是何其“外部”类的实例相关的,并且是可以直接方法该对象的方法和字段的。由于内部类是和一个对象相关的,因此其自身是不能定义静态成员的。

内部类的对象存在于该内部类的“外部”类的对象中。假设有如下的类:

class OuterClass{
    …
   class InnerClass{
        …
    }
}

一个内部类的实例仅仅只可以存在于其“外部”类的实例中,并且是可以访问其外类的实例字段和方法的。下面的图就展示了这点:


内部类的对象存在于外部类的对象中

如果想要对内部类进行实例化,就必须先要对外部类进行实例化。然后如下的语句来在外部类的对象中创建内部类的对象:

OuterClass.InnerClassinnerObject = outerObject.new InnerClass();

另外,有两种特殊的内部类:本地类(Local class)和匿名类(anonymousclass,有时候也被称为是匿名内部类)。我们将在下一个小节中对这两种特殊的内部类进行讨论。

注意:如果你想要知道更多关于Java编程语言中的不同种类的类的信息,则可以阅读Joseph Darcy的博客:Nested,Inner, Member and Top-Level classes

内部类示例

为了演示如何使用内部类,我们先来考虑一个关于数组的示例。在下面的示例程序中,我们将会创建一个数组,并使用整形数来对其进行填充,然后我们只输出其中索引为偶数的元素的值,并且是以升序的方式来输出的。

其中的类DataStructure有一下几部分组成:

  •  外部类DataStructure中包含了将一个整型数加入到数组中的方法(译者好像没有看到这个方法!)和打印出偶数索引的值的方法。
  •  内部类InnerEvenIterator和标准的java迭代器(iterator)有些类似。迭代器是用来对数据结构进行遍历,并且通常都含有用来检查是否已经是最后一个元素,获取当前元素,移动到下一个元素的方法。
  •  main方法中,生成了一个DataStructure类的对象,并使用它来把数组arrayOfInts填充为整型数值0,1,2,3,…,然后调用printEvent方法来打印arrayOfInts数组中的偶数索引对应的值。

public class DataStructure {
    // create an array
    private final static int SIZE= 15;
    private int[] arrayOfInts =new int[SIZE];
   
    public DataStructure() {
        // fill the array withascending integer values
        for (int i = 0; i <SIZE; i++) {
            arrayOfInts[i] = i;
        }
    }
   
    public void printEven() {
        // print out values ofeven indices of the array
        InnerEvenIterator iterator= this.new InnerEvenIterator();
        while (iterator.hasNext()){
           System.out.println(iterator.getNext() + " ");
        }
    }
   
    // inner class implements theIterator pattern
    private classInnerEvenIterator {
        // start stepping throughthe array from the beginning
        private int next = 0;
       
        public boolean hasNext() {
            // check if a currentelement is the last in the array
            return (next <=SIZE - 1);
        }
       
        public int getNext() {
            // record a value ofan even index of the array
            int retValue =arrayOfInts[next];
            //get the next evenelement
            next += 2;
            return retValue;
        }
    }
   
    public static void main(Strings[]) {
        // fill the array withinteger values and print out only
        // values of even indices
        DataStructure ds = newDataStructure();
        ds.printEven();
    }
}

其输出结果如下;

0 2 4 6 8 10 12 14

注意在上面的程序中,内部类InnerEventIterator中直接访问了DataStructure类的实例变量。

内部类可以被用来实现诸如上述代码中的起辅助功能的类。如果我们的程序需要处理用户交互事件,那么我们有必要知道如何使用内部类,因为事件处理机制中大量地采用了内部类。

本地和匿名的内部类

除了上面所说之外,还有两种特别的内部类。在方法中声明的内部类被称为是本地内部类(Local inner class)。另外还在在方法中声明没有命名的内部类,这些类被称为是匿名内部类(anonymous inner class)。我们会在高级的java编程中遇到这些类。

修饰符

可用于内的其他成员的修饰符都可用于修饰内部类。例如,可以使用访问限定修饰符——private,public和protected——来限制对内部类的访问权限,这和别的类成员是一样的。

嵌入类的小结

被定义在别的类中的类被称为是嵌入类。和其他的类的成员一样,嵌入类可以被声明为是静态的或者是非静态的。非静态的嵌入类又被称为是内部类。内部类的实例是仅存在于包含它的外部类的实例中的,并且是可以访问其外部类的成员的, 即使这些成员是私有的。

下面的表格给出了嵌入类的类别:

类型

范围

内部类

静态嵌入类

成员

内部类(非静态的嵌入类)

成员

本地类(局部类)

本地(局部)

匿名类

仅限于定义它的地方


 原文:http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值