1. 程式人生 > 實用技巧 >內部類詳解

內部類詳解

  • static關鍵字基本概念
      我們可以用一句話來概括:方便在沒有建立物件的情況下來進行呼叫。也就是說:被static關鍵字修飾的不需要建立物件去呼叫,直接根據類名就可以去訪問。

  • 什麼是內部類
      大部分時候,類被定義成一個獨立的程式單元。在某些情況下,也會把一個類放到另一個類的內部定義,這個定義在其他類內部的類就被稱為內部類(有些地方也叫做巢狀類),包含內部類的類也被稱為外部類(有些地方也叫做宿主類)。
      Java的內部類主要分為 成員內部類、區域性內部類、匿名內部類、靜態內部類

  • 成員內部類與區域性內部類

1.成員內部類與區域性內部類的區分

package com.vg.demo03;
/**
 * 內部類的位置:
 * 	1.成員位置——>成員變數
 * 	2.區域性位置——>區域性變數
 * */
//外部類
public class Outer {
	private int num;
	//成員內部類 --- 成員變數
        //內部類——>成員位置
	public class Inner{
		
	}
	
	public void method() {
		int num;
		//區域性內部類---區域性變數
                //內部類——>區域性變數
		class Inner{
			
		}
	}
}
//成員內部類變數名方法名和區域性內部類可以一樣

2.成員內部類與區域性內部類的訪問特點

內部類可以直接訪問外部類的成員,包括私有。
外部類要訪問內部的成員,必須建立物件

package com.vg.demo03;

/**
 * 內部類的訪問——內部類造物件
 * 成員內部類造物件
 * */

//外部類
class Outer {
	private int num = 10;
	
	public void method2() {
		//外部類中訪問內部類的成員
		//必須建立內部類物件
		System.out.println("====呼叫method2===");
		System.out.println("method2...");
		//成員內部類物件建立
		Inner i = new Inner();
		System.out.println(i.i);
		//靜態成員內部類物件建立
		Inner3 i3 = new Inner3();
		i3.method();
	}
	
	public static int num2;
	
	//靜態內部類
	public static class Inner3{
		public void method() {
			System.out.println("===靜態內部類===");
			System.out.println("method");
			//靜態成員不能訪問非靜態的
			//method2();
			//System.out.println(num);
		}
	}
	
	//成員內部類
	public class Inner{
		private int i = 1000;
		public void method() {
			System.out.println("===成員內部類===");
			System.out.println(num);
			method2();
		}
	}
	
	public void method() {
		//int num;
		//區域性內部類
		class Inner2 {
			public void method1() {
				System.out.println("===區域性內部類==");
				System.out.println(num);
				method2();
			}
		}
		//區域性內部類只能在區域性範圍使用
		Inner2 i2 = new Inner2();
		i2.method1();
	}
}

public class OuterTest{
	public static void main(String[] args) {
		//建立外部類物件,都是在外部類外部
		
		//成員內部類造物件
		//Inner i = new Inner(); 普通類 錯誤寫法
		//格式:外部類名.內部類名 i = new 外部類().new 內部類();
		Outer.Inner oi = new Outer().new Inner();
		oi.method();//成員內部類物件的使用
		//建立外部類物件
		//呼叫方法
		//執行區域性內部類物件的方法
		
		Outer o = new Outer();
		o.method();
		//區域性內部類物件的使用
		
		o.method2();
		
		//靜態內部類造物件
		//類名.靜態變數名
		//格式: 外部類名.內部類名 i = new 外部類 new 內部類();
		Outer.Inner3 oi3 = new Outer.Inner3();
		oi3.method();
	}
}

  • 內部類的作用
    1、更好的封裝性
    2、內部類成員可以直接訪問外部類的私有資料,因為內部類被當成其外部類成員,但外部類不能訪問內部類的實現細節,例如內部類的成員變數
    3、匿名內部類適合用於建立那些僅需要一次使用的類

  • 靜態類(只有內部類才能被宣告為靜態類,即靜態內部類(也可稱為類內部類))---靜態成員變數
    1、只能在內部類中定義靜態類
    2、靜態內部類與外層類繫結,即使沒有建立外層類的物件,它一樣存在。
    3、靜態類的方法可以是靜態的方法也可以是非靜態的方法,靜態的方法可以在外層通過靜態類呼叫,而非靜態的方法必須要建立類的物件之後才能呼叫。
    4、只能引用外部類的static成員變數(也就是類變數)。
    5、如果一個內部類不是被定義成靜態內部類,那麼在定義成員變數或者方法的時候,是不能夠被定義成靜態的。

  • 靜態類與非靜態類的區別

package com.vg.demo03;

//程式碼來分析靜態內部類與非靜態內部類的區別
public class OutClassTest {
	
	int out1 = 1;
	static int out2 = 1 ;
	
	void out() {
		System.out.println("非靜態");
	}
	static void outstatic() {
		System.out.println("靜態");
	}
	
	public class InnerClass{
		void InnerClass() {
			System.out.println("innerClass!");
			System.out.println(out1);
			System.out.println(out2);
			out();
			outstatic();//靜態內部類只能訪問外部類的靜態成員
		}
		
		//static void inner(){}
		//static int i=1;
		//非靜態內部類不能有靜態成員(方法、屬性)
		
		
	}
	
	public static class InnerstaticClass{
		void InnerstaticClass() {
			System.out.println("InnerstaticClass");
			//靜態內部類只能訪問外部類的靜態成員
			//out();
			//System.out.println(out1);
			outstatic();
			System.out.println(out2);
		}
		//靜態內部類能有能有靜態成員(方法、屬性)
		static void innerstatic() {}
		static int i = 1;
	}
	public static void main(String[] args) {
		OutClassTest a = new OutClassTest();
		OutClassTest.InnerstaticClass b = new OutClassTest.InnerstaticClass();//建立靜態內部類
		OutClassTest.InnerClass c = a.new InnerClass();
		System.out.println(a.out1);
		System.out.println("====");
		System.out.println(a.out2);
		System.out.println("====");
		a.out();
		System.out.println("====");
		a.outstatic();
		System.out.println("====");
		c.InnerClass();
		System.out.println("====");
		b.InnerstaticClass();
	}

}

1.是否能擁有靜態成員
  靜態內部類可以有靜態成員(方法,屬性),而非靜態內部類則不能有靜態成員(方法,屬性)。
2.訪問外部類成員
  靜態內部類只能夠訪問外部類的靜態成員,而非靜態內部類則可以訪問外部類的所有成員(方法,屬性),外部類的靜態成員不可以直接使用非靜態內部類。
3.靜態內部類和非靜態內部類在建立時有區別
  //假設類A有靜態內部類B和非靜態內部類C,建立B和C的區別為:
  A a=new A();
  A.B b=new A.B(); //靜態內部類
  A.C c=a.new C();