内部类详解

  在一个类中定义的类叫做内部类。内部类分为四种:成员内部类,静态内部类,局部内部类,匿名内部类

1.成员内部类---在一个类中定义,类似于成员变量

/**
 * 成员内部类
 * 内部类属于外部类的一个成员,所以内部类可以直接使用外部类的成员
 *
 */

class Outer{
	int num = 2;
	class Inner{
		public void show(){
			System.out.println(num);
		}
	}
	public void fun(){
		Inner inner = new Inner();
		inner.show();
	}
}

public class Test {
	
	public static void main(String[] args) {
		
		Outer  outer = new Outer();
		outer.fun();
		
		//直接创建内部类对象
		Outer.Inner inner = new Outer().new Inner();
		inner.show();
	}

}

 运行结果:

       2

   2

成员变量num,成员函数fun,成员内部类Inner,都是Outer的成员,三者可以相互调用。

show()依附于Inner,Inner依附于Outer-----获取show(),要获取new Inner()---要获取new Inner(),要获取new Outer()

Outer.class与Inner.class的字节码文件的名称如下:

Outer.class----Outer$Inner.class

2.静态内部类---static修饰

 1 //静态内部类
 2   class Outer{
 3       static int num = 2;
 4       static class Inner{
 5           public void show(){
 6              System.out.println(num);
 7          }
 8      }
 9      public void fun(){
10          Inner inner = new Inner();
11          inner.show();
12      }
13  }
14 
15  public class Test {
16      
17      public static void main(String[] args) {
18          
19          Outer  outer = new Outer();
20          outer.fun();
21          
22          //直接创建内部类对象
23          Outer.Inner inner = new Outer.Inner();
24            
25       //这是错误的
26       //Outer.Inner inner = new Outer.new Inner();
27          inner.show();
28           }
29   }                          

 运行结果:

      2

   2

成员变量num,成员函数fun,静态内部类Inner,都是Outer的成员。

show()依附于Inner,Inner依附于Outer-----获取show(),要获取new Inner()---要获取new Inner(),直接Outer点取 Outer.Inner

/**
 * 内部类中含有静态成员,那么内部类必须为static
 */
class Outer{
	static int num = 2;
	static class Inner{
		//内部类中含有静态成员,那么内部类必须为static
		public static void show(){
			System.out.println(num);
		}
	}
	public void fun(){
		Inner inner = new Inner();
		inner.show();
	}
}

public class Test {
	
	public static void main(String[] args) {
		
		Outer  outer = new Outer();
		outer.fun();
		
		//直接创建内部类对象
		Outer.Inner inner = new Outer.Inner();
		inner.show();
	}

}

  

运行结果:

      2

   2

成员变量num,成员函数fun,静态内部类Inner,都是Outer的成员。

show()依附于Inner,Inner依附于Outer-----获取show(),要获取new Inner()---要获取new Inner(),直接Outer点取 Outer.Inner

 /* * 内部类得到外部类对象中的成员 外部类名.this.成员 **/

 1 class Outer{ 
 2     int num = 2;    
 3     class Inner{
 4         int num =3;
 5         //内部类中含有静态成员,那么内部类必须为static
 6         public void show(){
 7             int num =4;
 8             System.out.println(num);
 9             System.out.println(this.num);
10             System.out.println(Outer.this);
11             System.out.println(Outer.this.num);
12        //会出现错误
13            //System.out.println(Outer.num);
14       }
15     }
16     public void fun(){
17         Inner inner = new Inner();
18         inner.show();
19     }
20 }
21 
22 public class Test {    
23     public static void main(String[] args) {        
24         Outer outer = new Outer();
25         outer.fun();        
26     }
27 }                    

  

运行结果: 

  4
  3
  langdon.Outer@40671416
  2

System.out.println(Outer.this)输出的是Outer对象

3.局部内部类:在函数内部定义的类

/**
 * 局部内部类
 * 局部内部类使用了其所在函数的局部变量时,该局部变量必须是final的
 *
 */
class Outer{
	
	public void fun(){
		final int num = 2;
		class Inner{
			public void show(){
				//从内部类中访问本地变量num,num需要声明为final
				System.out.println(num);
			}
		}
		Inner inner = new Inner();
		inner.show();
	}
}

public class Test {
	
	public static void main(String[] args) {
		
		Outer outer = new Outer();
		outer.fun();
		
	}

}

  

运行结果: 

  2

class Outer{
	Object obj;
	public void fun(){
		
		final int num = 2;
		class Inner{
			public void show(){
				//从内部类中访问本地变量num,num需要声明为final
				System.out.println("inner"+num);
			}
			
			public String toString() {
				return "inner"+num;
			}
		}
		obj = new Inner();//多态
	}
	
	public void function(){
		System.out.println(obj.toString());
	}
}

public class Test {
	
	public static void main(String[] args) {
		
		Outer outer = new Outer();
		outer.fun();
		outer.function();
		
	}

}

  

运行结果: 

  inner2


4.匿名内部类:没有名字的内部类
(1)非匿名内部类----->匿名内部类(前提条件:存在父类)

 1 /**
 2  * 匿名内部类:没有名字的内部类
 3  * 简化书写
 4  * 前提条件:存在父类(TestMain)或父接口
 5  *
 6  */
 7 abstract class TestMain{
 8   public abstract void show();
 9 }
10 
11 class Outer{
12 
13   class Inner extends TestMain{
14 
15      public void show(){
16 
17       System.out.println("show");
18 
19      }
20     
21         
22      public void eat() {
23       System.out.println("吃饭");
24      }
25     
26 
27     }
28     
29     public void fun(){
30       Inner inner = new Inner();
31       inner.show();
32       inner.eat();        
33     }
34 
35     
36 }
37 
38 
39 public class Test {
40 
41   public static void main(String[] args) {
42   //
43   Outer outer = new Outer();
44   outer.fun();        
45   
46   }
47     
48 }
 1 /**
 2  * 匿名内部类:没有名字的内部类
 3  * 简化书写
 4  * 前提条件:存在父类(TestMain)或父接口
 5  *
 6  */
 7 
 8 abstract class TestMain{
 9   public abstract void show();
10 }
11 
12 class Outer{
13   class Inner extends TestMain{
14     public void show(){
15       System.out.println("show");
16     }
17         
18     public void eat() {
19       System.out.println("吃饭");
20     }
21 
22   }
23 
24   public void fun(){
25     //创建TestMain的子类对象
26     new TestMain(){
27       public void show(){
28         System.out.println("show");
29       }
30         
31       public void eat() {
32         System.out.println("吃饭");
33       }
34     }.show();
35     
36     new TestMain(){
37       public void show(){
38         System.out.println("show");
39       }
40         
41       public void eat() {
42         System.out.println("吃饭");
43       }
44     }.eat();
45     
46    }
47 
48 }
49 
50 public class Test {
51   public static void main(String[] args) {
52   //
53   Outer outer = new Outer();
54   outer.fun();
55   }
56 }

  
运行结果: 

  show

  吃饭

(2)匿名内部类(父类类型的引用指向了子类对象)

abstract class TestMain{
	public abstract void show();
}

class Outer{
	class Inner extends TestMain{
		public void show(){
			System.out.println("show");
		}
		
		public void eat() {
			System.out.println("吃饭");
		}

	}

	public void fun(){
		//父类类型的引用指向了子类对象,只能调用show()
		TestMain testMain = new TestMain(){
			public void show(){
				System.out.println("show");
			}
					
			public void eat() {
				System.out.println("吃饭");
			}
		};
				
		testMain.show();
				
		System.out.println(new Object(){
			int age = 23;
			String name = "11";
					
			public String toString(){
				return name+","+age;
			}
		});					
	}

}

public class Test {
	public static void main(String[] args) {
	  //类
	  Outer outer = new Outer();
	  outer.fun();
	}
}

  

运行结果: 

  show
  11,23

(3)匿名内部类(前提条件:存在父接口)

interface inter{
	public abstract void sleep();
}

class Test1 implements inter{
	public void sleep(){
		System.out.println("睡觉");
	}
}

public class Test {
	
	public static void main(String[] args) {
		//接口
		Test1 t = new Test1();
		ff(t);
		
		//使用匿名内部类调用函数ff
		ff(new inter(){
			public void sleep(){
				System.out.println("睡觉");
			}
			public void learn(){
				System.out.println("学习");
			}
		});
		
	}
	
	public static void ff(inter in){//inter in = new Test1()
		in.sleep();
	}

}

 

运行结果: 

  睡觉
  睡觉

 

原文地址:https://www.cnblogs.com/langdon/p/6294074.html