成员内部类

成员内部类

成员内部类又称实例内部类,作为外部类的一个成员存在,与外部类的属性、方法并列
成员内部类中,不能定义静态成员,可以访问外部类的所有成员,在内部类中访问外部类中与内部类同名的实例变量用外部类名.this.变量名如果内部类中没有与外部类同名的变量,则可以直接用变量名访问外部类变量。


话不多说,还是在程序中体现以上的要点:

/** 外部类 */
class OuterClass{
	//作为外部类的一个成员存在,与外部类的属性、方法并列。
	private int data1 = 1000;
	private int a = 20;
	private static int b = 30;
	private static final int d = 40;
	
	public OuterClass(){
		System.out.println("OuterClass() init!");
	}
	
	public void print(){
		System.out.println("OuterClass print()!!" );
	}
		
	
	 /** 成员内部类 */
	 class InnerClass{
		// 内部类和外部类的实例变量可以共存
		private int data1 = 10;
		private int data2 = 20;
		//private static int data3 = 30; //成员内部类中不能定义静态成员,详见下面解释
		// final修饰的为立即数
		private static final int data4 = 30; 
		//private static final int data5 = data1+30;// 内部类是一个编译时的概念,而data1只有在运行时才能确定
		private static final int data6 = data4 + 30;   // 立即数
		public InnerClass(){
			System.out.println("InnerClass() init!!");
		}
		
		public void print(){
			// 如果内部类中没有与外部类同名的变量,则可以直接用变量名访问外部类变量
			System.out.println("a = " + a);
			System.out.println("b = " + b);
			//在内部类中访问外部类中与内部类同名的实例变量用外部类名.this.变量名
			System.out.println("data1 : " + OuterClass.this.data1);
			//在内部类中访问内部类自己的变量可以直接变量名,也可以用this.变量名
			System.out.println("data2 : " + this.data2);
			System.out.println("data2 : " +data2);
		}
		public void print1() {
			System.out.println("这是一个空方法");
		}
	}

		/** 外部类的静态方法访问成员内部类,与在外部类外部访问成员内部类一样 */
		public static void outerFun() {
		// 先实例化一个内部类对象
		OuterClass out = new OuterClass();
		// 根据外部类对象建立内部类对象
		OuterClass.InnerClass in1 = out.new InnerClass();
		// 然后通过内部类对象调用
		in1.print1();
		}
		
		/** 外部类的非静态方法访问成员内部类 */
		public void outerFun1() {
		// 先实例化一个内部类对象
		InnerClass in2 = new InnerClass();
		// 然后通过内部类对象调用
		in2.print1();
		}	
}
	
/** 主类 */
public class Demo {
	public static void main(String[] args) {
		// 访问内部类方法 
		OuterClass outer = new OuterClass();
		OuterClass.InnerClass in = outer.new InnerClass();
		in.print();
		// 访问外部类然后调用内部类方法 
		outer.outerFun();
		outer.outerFun1();
	}
}

结果是:

		OuterClass() init!          // 每次调用类方法时先执行类的构造方法
		InnerClass() init!!
		a = 20
		b = 30
		data1 : 1000
		data2 : 20
		data2 : 20
		InnerClass() init!!
		这是一个空方法
		InnerClass() init!!
		这是一个空方法


关于为什么不能在成员内部类中使用static关键字修饰变量或方法的解释

解释一:从static类型的加载过程层面解释

  static类型的属性和方法,在类加载的时候就会存在于内存中。而非静态内部类并不随外部类一起加载,只有在实例化外
部类之后才会加载。外部类并没有实例化,内部类还没有加载,此时却试图在内存中创建并调用该内部类的静态成员,这明
显是矛盾的。故成员内部类中不能有静态成员变量或静态方法。

解释二:从成员内部类的设计意义解释:

  通过static修饰成为类的方法,使用时用“类名.方法名”的方式就可以调用,相当于定义了一个全局的函数。而内部类的
设计目的是每一个实例内部类必须有一个外部类对象与其对应,内部类依赖与外部类对象。很明显,这两者完全相悖,故内部
类中不能使用static关键字。

关于为什么内部类的成员变量要用final修饰的解释

	java类加载顺序,首先加载类,执行static变量初始化,接下来执行对象的创建,如果我们要执行代码中的变量int a 
初始化,那么必须先执行加载外部类,再加载内部类,最后初始化静态变量 a ,问题就出在加载内部类上面,我们可以把内部类
看成外部类的非静态成员,它的初始化必须在外部类对象创建后以后进行,要加载内部类必须在实例化外部类之后完成 ,java
虚拟机要求所有的静态变量必须在对象创建之前完成,这样便产生了矛盾。
	而java常量放在内存中常量池,它的机制与变量是不同的,编译时,加载常量是不需要加载类的,所以就没有上面那种矛盾。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值