标签:构造器 没有 外部 程序包 java基础 rgs some 范围 evel
??Java允许在一个类中定义另外一个类,这样的类被称为嵌套类,就像下面这样:
class OuterClass {
...
class NestedClass {
...
}
}
??嵌套类分为两种:静态的和非静态的。声明为static的嵌套类被称为静态嵌套类,非静态嵌套类则被称为内部类:
class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}
??嵌套类是其所在的外部类的成员。内部类可以访问外部类中的其他成员,即使这个成员被private修饰。静态嵌套类则没有访问外部类中其他成员的权限。作为外部类的一个成员,嵌套类可以被声明为private、public、protected或者包私有的。
??下面是几个为什么要使用嵌套的类原因:
??就像静态方法和静态变量一样,静态嵌套类是和外部类相关联的。和静态方法一样,静态嵌套类不能直接引用实例变量和实力方法,只能通过一个对象引用。实际上,可以将静态嵌套类看作是一个顶级类,只不过将其嵌套在其他类中方便打包。
??静态嵌套类可以用过外部类的名字去访问:
OuterClass.StaticNestedClass
??可以使用下面的语法为静态嵌套类创建对象:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
??就像实例方法和实例变量一样,内部类与外部类的实例相关联并且可以直接访问外部类的方法和成员。并且,因为内部类与外部类的实例相关联,因此它内部不能定义静态成员。
??要实例化内部类,必须创建外部类的对象,然后使用这个对象去创建内部类的对象:
OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
??实际上,还有两种特殊的内部类————局部类和匿名类。有关这两种类的内容将会在下文中介绍。强烈建议不要对内部类(包括局部类和匿名类)进行序列化(把对象转换为字节序列的过程称为对象的序列化,有关序列化的内容会在以后的文章中进行介绍)。
??如果一个类型(例如成员变量或参数)与外部作用域中的类型同名,那么内部作用域中的声明将会屏蔽外部作用域中的声明,这样就不能直接通过名称去访问外部作用域中同名的类型。如下例所示:
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
??这个例子中定义了三个名为x的变量,分别是ShadowTest类的成员变量,内部类FirstLevel的成员变量,以及方法methodInFirstLevel的参数。方法methodInFirstLevel的参数x屏蔽了内部类FirstLevel的成员变量x和ShadowTest类的成员变量x。因此,在表示内部类FirstLevel的成员变量x时,要像下面这样:
System.out.println("this.x = " + this.x);
??在表示ShadowTest类的成员变量x时,要像下面这样:
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
??局部类是在块(由大括号包围的零条或多条语句)中定义的类。经常会在方法体中见到局部类。下面是一个定义在方法中的局部类:
public class OuterClass {
public void method() {
...
class LocalClass {
...
}
}
}
??局部类可以访问外部类的成员。此外,局部类还可以访问局部变量。然而,局部类只能访问由final修饰的局部变量。当一个局部类访问一个块中的局部变量或参数时,它就捕获了这个变量或者参数。从Java8开始,局部类不但可以访问由final修饰的局部变量和参数,还可以访问近似final的局部变量和参数。近似final的意思是说这个变量或参数的值自从初始化之后就没有修改过。此外,局部类中的变量也会屏蔽定义在外部的同名变量或参数。
??局部类中基本不能定义静态成员。不过也有例外,可以在局部类中定义静态常变量(常变量是指类型为基本数据类型或者String,被声明为final,并且使用编译时常量表达式进行初始化的变量。编译时常量表达式通常是可以在编译时计算的字符串或算术表达式)。
??定义在静态方法中的局部类,只能引用外部类的静态成员。不能在块中定义接口,因为接口是天生静态的。也不能在局部类中定义静态初始化器或者接口。
??匿名类让代码看上去更加简洁,它能让你同时声明和实例化一个类。它们类似于局部类,只不过匿名类没有名称。如果某个局部类只使用一次,可以将它定义为匿名类。
??局部类是类的声明,而匿名类则是表达式,这意味着匿名类是在一个表达式中定义的。匿名类表达式的语法就像是调用构造器的语法,只不过构造器后面跟的是类的定义。就像下面这样:
HelloWorldInterface frenchGreeting = new HelloWorldInterface() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
??匿名类的语法包含以下几部分:
??就像局部类一样,匿名类也可以捕获变量。下面是几条规则:
??匿名类在成员的定义上和局部类有相同的规则:
??可以在匿名类中声明以下元素:
??不能在匿名类中定义构造方法。
标签:构造器 没有 外部 程序包 java基础 rgs some 范围 evel
原文地址:https://www.cnblogs.com/maconn/p/10126128.html