天天看点

成员内部类总结与静态内部类详述

成员内部类总结

由上一篇《java中的成员内部类》大致了解了成员内部类的一些相关知识,在此总结一下(详细 请见上一篇:《java中的成员内部类》):

1、内部类可以直接访问外部类的所有数据,包括私有数据(即用private修饰的成员变量或方法)。

2、内部类可以使用任意访问控制符。

3、外部类不能直接访问内部类的成员变量和方法(即使内部类的成员变量和方法均被public修饰),如需访问应先创建内部类的对象,之后通过内部类的对象来访问其成员变量和方法,

例:外部类为HelloWorld ,内部类为Inner 。

那么创建内部类:(1):创建外部类对象hello     HelloWorld hello = new HelloWorld();

(2):创建内部类对象inHelloWorld.Inner in =  hello.new Inner();  或者使用;Inner in = hello.new Inner();

4、若外部类和内部类具有相同命名的成员变量和方法,内部类默认访问自己的成员变量和方法,如要访问外部类的成员变量或方法需要使用this关键字;

例:外部类为HelloWorld ,内部类为Inner 。同名成员变量为name。

内部类访问其自己的name:直接使用name 或this.name

访问外部类的name: HelloWorld.this.name

5、带内部类的外部类编译后会生成两个.class文件:HelloWorld.class 与 HelloWorld$Inner.class

静态内部类

在此基础上我们可以继续深入思考:既然内部类可以直接调用外部类的成员变量和方法,那么如果内部类为静态时(即有修饰符static)会怎样?

(我们知道,静态的类不能调用非静态的方法,同样static成员不能访问非static的成员)

静态内部类:即用static修饰的内部类

特点:

1、如果外部类的静态成员与内部类的成员同名(无论该内部类的成员是否为静态)可通过“类名.静态成员名”访问外部类静态成员【见代码第17行】。如果外部类有静态成员且与内部类的成员名不同时(无论该内部类的成员是否为静态),可以通过成员名直接调用外部类的静态成员【见代码第16行】

(注:即使外部类不是静态类,也可以在外部类中声明静态成员,这表明外部类与普通的类是一致的)。

2、静态内部类可以直接访问外部类的静态成员与静态方法,而不能直接访问外部的非静态成员,但可以通过  "new 外部类().成员"的方式访问外部非静态成员。

【见代码第18行】。

3、创建内部静态对象时不需要外部的对象,可以直接创建:内部类 对象名 = new  内部类();【见代码第25-28行】

除此静态类内部的使用限制:(详见:http://blog.sina.com.cn/s/blog_5da93c8f0100wib7.html  )

1、在非静态内部类中不可以声明静态成员

如现在在一个外部类HelloWorld类中定义了一个内部类Inner,如果没有将这个内部类用static关键字修饰,既没有定义为静态类,那么在这个类内部中如果要利用

static关键字来修饰某个成员方法或者变量是不允许的。在编译的时候无法通过。故应注意:只有静态内部类才能够定义静态的成员变量与成员方法。

(在外部类中即使外部类没有被static修饰即不是静态外部类,其外部类的成员变量也可以定义为static,这一点与内部类不同。上面的特点1已经 用到但未细说,这表明外部类与普通类是一致的)

代码实例:(来源:慕课网)

//外部类
public class HelloWorld_static {
    
    // 外部类中的静态变量score,与内部类中一非静态变量同名
    private static int score = 84;
    // 外部类中的静态变量age,不与内部类中变量同名
    private static int age = 20;
    // 外部类中的非静态变量num
    private int num = 90;
    // 创建静态内部类
	public   static  class SInner {
        // 内部类中的变量score
        int score = 91;
        
		public void show() {
		    System.out.println("访问外部类中的age:" + age);
			System.out.println("访问外部类中的score:" + HelloWorld1_static.score  );
			System.out.println("访问外部类中的num:" + new HelloWorld_static().num);
			System.out.println("访问内部类中的score:" + score);
		}
	}

	// 测试静态内部类
	public static void main(String[] args) {
	    // 直接创建内部类的对象
	    SInner si = new SInner();
	    //调用show方法
		si.show();
	}
}