Java内部类详解(三)

四、静态内部类与非静态的区别

首先,静态内部类实际上与普通类(即类名必须与文件名一样的顶级类)一样,只是静态内部类在某一类的内部定义了而已,既然是类,要想使用就必须实例化。概念上与静态变量、静态方法是不一样的,不要被“静态”两个字迷惑了(不要以为凡是静态的东西就不需要实例化就可以直接使用,静态内部类是有区别),而且只有静态内部类,而没有静态类(顶级类)的概念。例如,下面定义类是错误的:

public static class TestClass { // 此写法错误,不存在静态类,编译不通过

	public void test() {
		
	}
}

如果你不需要内部类对象与其外部类对象之间有联系,那你可以将内部类声明为static。这通常称为嵌套类(nested class)。Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。想要理解static应用于内部类时的含义,你就必须记住,普通的内部类对象隐含地保存了一个引用,指向创建它的外部类对象。然而,当内部类是static的时,就不是这样了。嵌套类意味着:

1. 嵌套类的对象,并不需要其外部类的对象。

2. 不能从嵌套类的对象中访问非静态的外部类对象。

如下所示代码为定义一个静态嵌套类:

public class StaticTest {
	private static String name = "woobo";
	private String num = "X001";

	static class Person { // 静态内部类可以用public,protected,private修饰

		// 静态内部类中可以定义静态或者非静态的成员
		private String address = "China";

		private static String x = "as";
		public String mail = "[email protected]";// 内部类公有成员

		public void display() {
			// System.out.println(num);//不能直接访问外部类的非静态成员

			// 静态内部类不能访问外部类的非静态成员(包括非静态变量和非静态方法)
			System.out.println(name);// 只能直接访问外部类的静态成员

			// 静态内部类只能访问外部类的静态成员(包括静态变量和静态方法)
			System.out.println("Inner " + address);// 访问本内部类成员。
		}
	}

	public void printInfo() {
		Person person = new Person();

		// 外部类访问内部类的非静态成员:实例化内部类即可
		person.display();

		// System.out.println(mail);//不可访问
		// System.out.println(address);//不可访问
		System.out.println(person.address);// 可以访问内部类的私有成员

		System.out.println(Person.x);// 外部类访问内部类的静态成员:内部类.静态成员
		System.out.println(person.mail);// 可以访问内部类的公有成员
	}

	public static void main(String[] args) {
		StaticTest staticTest = new StaticTest();
		staticTest.printInfo();
	}
}

总结:

1. 静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。

2. 静态内部类只能够访问外部类的静态成员,而非静态内部类则可以访问外部类的所有成员(方法,属性)。

3. 实例化一个非静态的内部类的方法:

a. 先生成一个外部类对象实例

OutClassTest oc1 = new OutClassTest();

b. 通过外部类的对象实例生成内部类对象

OutClassTest.InnerClass no_static_inner = oc1.new InnerClass();

4. 实例化一个静态内部类的方法:

a. 不依赖于外部类的实例,直接实例化内部类对象

OutClassTest.InnerStaticClass inner = new OutClassTest.InnerStaticClass();

b. 调用内部静态类的方法或静态变量,通过类名直接调用

OutClassTest.InnerStaticClass.static_value

OutClassTest.InnerStaticClass.getMessage()


最后,我再告诉大家,接口虽然不能有任何实现,但内部类(无论是静态的还是非静态的内部类)却可以作为接口的一部分,例如:

public interface TestInterface {

	void testMethod();
	
	static class TestInnerClass implements TestInterface {// 并不是非要实现TestInterface,这里可以做任何事情。

		@Override
		public void testMethod() {
			System.out.println("测试");
		}
		
	}
}
class Test {

	public static void main(String[] args) {
		TestInnerClass testClass = new TestInterface.TestInnerClass();
		testClass.testMethod();
	}
}



你可能感兴趣的:(Java内部类详解(三))