嵌套类(Nested Classes)
概述
Java允许在一个类的内部定义一个类,这样的类称为嵌套类。例:
class OuterClass {
...
class NestedClass {
...
}
}
<span style="background:yellow">嵌套类分为两类:静态和非静态。 用static 修饰的嵌套类称为静态嵌套类,未使用static修饰的嵌套类称为内部类。 </span>
class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}
嵌套类是其所在类的成员。非静态嵌套类(内部类)可以访问所在类的其他成员(包括用private修饰的)。 静态嵌套类不能访问所在类的其他成员。嵌套类可以拥有private, public, protected, or package private等访问权限。 (外部类只能有public 或 package private两种访问权限)
使用内部类的原因
将仅在一处使用的类整合到使用该类的类中:若一个类仅对某个类有用,则直接将其嵌入该类中,让两个类耦合不失为一种合理的选择。使用这种嵌入式的“帮助类”可以使代码包的结构更简介。
增强封装:假设有两个外部类,A和B。B需要访问A类的私有成员。只有将B类封装进A类时,B类才能访问A类中声明的私有成员。与此同时,B类也与其所在类以外的类隔绝开来。
增强代码的可读性和可维护性: 当某个类只有在一个类中才会用到时,可以将其封装进该顶层类中。
静态嵌套类
静态嵌套类与其外部类类本身相关联。和静态方法一样,静态嵌套类不能直接引用其所在类的实例变量和实例方法。
<span style="background:yellow">Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience. </span>
使用内部类的外部类类名访问静态嵌套类:
OuterClass.StaticNestedClass
创建静态嵌套类:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
内部类
内部类与其外部类的实例相关联,可直接引用该实例的实例变量和实例方法。内部类本身不能定义静态成员。内部类的实例只能存在于其外部类的实例中。
创建内部类的实例时必须先创建其外部类的实例。之后可按下面的格式创建:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
存在两种特殊的内部类:
遮蔽(Shadowing)
若在某个具体作用域(例如内部类或方法签名)中定义的变量的变量名(例如成员变量或参数名)与外部类的作用域中定义的相同,则较小作用域中定义的变量会遮蔽较大作用域中定义的变量。因此不能仅凭变量名本身引用该变量。
例:
public class ShadowTest {
public int x = 0;
class FirstLevel {
public 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
总结
- 优先级 --> 方法签名中的变量> 内部类的成员变量 > 外部类的成员变量
- 访问方式 --> varibaleName this.variableName OuterClass.this.variableName
欢迎到作者github主页交流