您的位置:首页 > 其它

嵌套类(Nested Class)

2017-02-24 13:15 190 查看
嵌套类

静态嵌套类

非静态嵌套类(内部类【inner class】)

class OuterClass{
//...
class NestedClass{
//...
}
}


class OuterClass{
//...
static class NestedClass{}
class InnerClass{}
}


     嵌套类是它所在封装类的一个成员。非静态嵌套类(内部类)可以访问封装类的其他成员,包括声明为private的成员。静态嵌套类不能访问该风状态的其他成员。作为外部类的一个成员,一个嵌套类可以被声明为private,public,protected或者package private。

为什么使用嵌套类?

使用嵌套类的主要原因:

它将仅在一个地方使用的逻辑类组合在一块。如果一个类仅在另外一个类中使用,那么,前者在逻辑上绑定到后者上使得两者在一块。像帮助类的嵌套使得他们的包更加合理化。

提高封装性。假如两个顶级类A和B,B需要访问A的private成员,通过将B嵌套在A中,A的成员可以被成名为private并且B可以访问它们。另外,B类也被隐藏起来了。

提高可读性和维护性。嵌套类使得它存在的地方靠近定义的地方。

静态嵌套类

     和类方法和变量一样,一个静态嵌套类和它的外部类是相关联的。类似静态类方法,一个静态嵌套类不能直接引用它所在封装类实例的变量和方法。它只能通过一个对象引用来使用它们。

     备注:一个静态嵌套类和它封装类的实例成员关系,就像任何其他顶级类一样。实际上,一个静态嵌套类行为和顶级类是一样的。

     静态嵌套类使用封装类名字来访问:

OuterClass.StaticNestedClass


创建一个静态嵌套类对象,语法如下:

new OuterClass.StaticNestedClass();


内部类

和实例方法和实例变量一样,一个内部类和封装类的实例有关系,可以直接访问封装类实例的方法和属性。同样,因为一个内部类和封装类的实例相关,它不能定义任何静态成员。

内部类的实例存在于外部类的实例中,下面例子:

class OuterClass{
class InnerClass{}
}


一个内部类的实例仅能够存在于外部类的实例中,并且可以直接访问外部类的方法和属性。

为了实例化一个内部类,你必须要先实例化外部类,创建内部类的语法如下:

OuterClass.InnerClass innerClass = new OuterClass().new InnerClass();


存在两种内部类:本地类(local classes)和匿名内部类(anonymous classes)

覆盖/隐藏(Shadowing)

如果在特拟定范围内(如内部类或者方法)的一个类型(如成员变量或者参数名称)定义和封装类的其他声明有相同的名字。然后这个声明将会覆盖掉封装类的声明。一个隐藏声明,你不能单独用它的声明来引用,如下ShadowTest所示:

public class ShadowTest{
public int x = 0;
class FirstLevel{
pulbic int x =1;
void methodInFirstLevel(int x){
System.out.println("x="+x);
System.out.println("this.x="+this.x);
System.out.println("ShadowTest.this.x="+ShadowTest.this.x);
}
}
public static void main(String... args){
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}


运行结果:

x=23
this.x=1
ShadowTest.this.x=0


这个例子中定义了三个名称为x的变量:类ShadowTest的成员变量,内部类FirstLevel的成员变量,和方法methodInFirstLevel的参数。方法methodInFirstLevel的参数x覆盖了内部类FirstLevel的成员变量,因此,当你在methodInFirstLevel中使用变量x,它引用的是方法参数。要用内部类FirstLevel成员变量,需要使用关键字this:

System.out.println("this.x="+this.x);


引用更大范围变量:

System.out.println("ShadowTest.this.x="+ShadowTest.this.x);


序列化

本地类和匿名类的序列化,强烈不推荐使用。当Java编译器编译指定构造器,如内部类,它创建复合构造;类、方法、属性和其他构造器,它们在源代码中没有相应的构造。复合构造让Java编译器可以实现新的Java语言特性而不用修改jvm。然而,复合构造非常不同于Java编译器实现,这意味着.class文件实现也非常不同。因此,在一个不同的jre实现中,如果你序列化一个内部类,可能会有容错问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息