Java四种内部类总结

一. 静态内部类

如何写一个静态内部类?

   

class OuterClass{
	private int a = 10;//实例数据成员
	private int b = 20;
	private static int c = 30;//静态成员
	private static final int d = 40;//被final修饰的静态数据成员,值无法改变
	
	public OuterClass(){//外部类的构造方法
		System.out.println("OuterClass()  init~~~~");
	}
	
	public void show(){
		System.out.println("OuterClass()  show~~~~");
	}
	//通过static修饰,静态内部类
	static class InnerClass{
		private int data1 = 10;
		private int data2 = 20;
		private int c = 100;
		private static int data3 = 30;
		
		public InnerClass(){//内部类的构造方法
			System.out.println("InnerClass  init~~~~");
		}
		public void show2(){
			System.out.println("InnerClass  show2()~~~~");
			System.out.println("innerclass c:"+c);
			System.out.println("outerclas c:"+OuterClass.c);//外部类的c是静态的,
								//通过类名.数据成员来访问
			System.out.println("d:"+d);
			
		}
		
		
	}
	
}
public class TestDemo2 {
	
	//静态内部类
	public static void main(String[] args) {
		//InnerClass in2 = new InnerClass();//不要这样写,会报错!
		OuterClass.InnerClass in = new OuterClass.InnerClass();
		in.show2();
	}
}

运行结果如图

当在静态内部类里访问外部类的静态数据成员是没有问题的,但是如果访问外部类的实例数据成员时,就会报错。如图


那么静态内部类如何访问外部类的实例成员变量?
 1.因为实例成员变量依赖于外部类的对象
 2.能否传入一个外部类对象(由构造函数传入)
 3.主函数内实例化一个外部类对象OuterClass outer = new OuterClass();
 4.在内部类的构造函数传入一个外部类的实例成员变量 OuterClass o2;
 5.接收外部类对象o2
 6.o2已经拿到了外部类对象
 7.System.out.println("a:"+o2.a);

static class InnerClass{
		private int data1 = 10;
		private int data2 = 20;
		private int c = 100;
		private static int data3 = 30;
		OuterClass o2;
		
		public InnerClass(OuterClass o){//内部类的构造方法
			o2 = o;//通过构造方法传入外部类对象
			System.out.println("InnerClass  init~~~~");
		}
		public void show2(){
			System.out.println("InnerClass  show2()~~~~");
			//System.out.println("a:"+a);//不可以访问外部类的成员,那怎么访问????
			System.out.println("outerclass a:"+o2.a);//通过外部类对象来访问外部类的非静态数据成员
			System.out.println("innerclass c:"+c);
			System.out.println("outerclass c:"+OuterClass.c);//外部类的c是静态的,
				                            //通过类名.数据成员来访问
			System.out.println("d:"+d);
			
		}
public static void main(String[] args) {
		OuterClass outer = new OuterClass();
		OuterClass.InnerClass in = new OuterClass.InnerClass(outer);
		in.show2();
	}

这样就可以访问外部类的实例数据成员啦


二. 实例内部类

class OuterClass2{
	private int data1 = 1000;
	private int a = 20;
	private int b = 20;
	private static int c = 30;//静态成员
	private static int d = 40;
	
	class InnerClass{//实例内部类,类似实例成员方法,依赖于外部类对象
		private int data1 = 10;
		private int data2 = 20;
		//private static int data3 = 30;//实例内部类里不能有静态成员方法,会报错
		private static final int data4 = 30;//编译时确定的立即数
		//private static final int data5 = data1 + 30;
		//static InnerClass in = new  InnerClass();
		public void show2(){
			System.out.println("InnerClass  show2()~~~~");
			System.out.println("data1:"+data1);//是内部类的
			System.out.println("data1:"+this.data1);//也是内部类的
			System.out.println("outer data1:"+OuterClass2.this.data1);//通过这种方法可以访问外部类的数据成员
			System.out.println("b:"+b);//可以访问,c和d也可以
		}
		
		public InnerClass(){
			System.out.println("InnerClass  init~~~~");
		}
	}
	public OuterClass2(){
		System.out.println("OuterClass()  init~~~~");
	}
	
	public void show(){
		System.out.println("OuterClass()  show~~~~");
	}
}

创建实例内部类对象

public static void main(String[] args) {
		OuterClass2 outer = new OuterClass2();
		//实例化一个内部类,依赖于外部类对象
		OuterClass2.InnerClass in = outer.new InnerClass();
		in.show2();
	}

1.为什么实例内部类中必须定义一个编译期间可以确定的立即数
  ---解释①一个类的初始化过程,先static   再实例方法 
  ---解释②实例内部类的设计意义
  -------每一个实例内部类必须有一个外部类对象,依赖外部类对象
   假设:static InnerClass in = new  InnerClass();成立
   OuterClass.InnerClass.in 可以直接拿到实例内部类的一个实例
     违背了设计意义(依赖外部类对象),有冲突。
  2.实例内部类有没有额外的内存消耗

  ---有的,还有外层类的this引用变量


三. 本地内部类

在方法内部的类

//本地内部类,在方法内部的类
	public void test(){
		final int data6 = 10;//局部变量
		class InnerClass{
			private int a = 10;
			//private static int b = 20;//报错
			private static final int c = 30;//编译期间所确定的立即数
			public InnerClass(){
				System.out.println("test() InnerClass  Init~~~~");
			}
			
			public void show(){
				System.out.println("a: "+a);
				System.out.println("c: "+c);
				System.out.println("data6: "+data6);
				System.out.println("test() show~~~~");
			}
		}
		InnerClass in = new InnerClass();
		in.show();
	}


四. 匿名内部类

相当于当前类的子类


public class TestDemo3 {
	
	public static void test(Student s){
		s.show();
	}
	
	//匿名内部类,相当于当前类的子类
	public static void main(String[] args) {
		new Student(){
			public void show(){
			System.out.println("niming  show()~~~~");
			}
		}.show();
		
	/*	test(new Student(){
			public void show(){
			System.out.println("niming  show()~~~~");
			}
		});*/
		
		
	}

猜你喜欢

转载自blog.csdn.net/sinat_37003267/article/details/80058544