1. 程式人生 > >java 四種內部類 使用細節(含程式碼)

java 四種內部類 使用細節(含程式碼)

一: 內部類

    定義在類體部,方法體部,甚至比方法體更小的程式碼塊內部的類(if 語句裡面等)

    1.靜態內部類(內部類中最簡單的形式)

        1.宣告在類體部,方法體外,並且使用static修飾的內部類
        2.訪問特點可以類比靜態變數和靜態方法
        3.脫離外部類的例項獨立建立
            在外部類的外部構建內部類的例項
                new Outer.Inner();
            在外部類的內部構建內部類的例項
                new Inner();

        4.靜態內部類體部可以直接訪問外部類中所有的靜態成員,包含私有

    
/**
 * @author gress
 *靜態內部類
 */
public class StaticInnerTest {
	public static void main(String[] args) {

		StaticOuter.StaticInner si = new StaticOuter.StaticInner();
		si.test2();
		//StaticOuter.StaticInner.test();
		System.out.println("si.b = "+si.b);
		System.out.println("si.a = "+si.a);
	//	System.out.println("StaticOuter.b  = "+StaticOuter.b);  這裡報錯
	}

}

class StaticOuter {
private int a = 100;
private static int b = 150;
public static void test(){
	System.out.println("Outer static test ...");
}
public  void test2(){
	System.out.println("Outer instabce test ...");
}	

	static class StaticInner {
		public  int a = 200;
		static int b =300;
		public static void test(){
			System.out.println("Inner static test ...");
		}
		public  void test2(){
			System.out.println("Inner instance test ...");
			StaticOuter.test();
			new StaticOuter().test2();
			System.out.println("StaticOuter.b  = "+StaticOuter.b);
		}	
	}
}


    2.成員內部類(例項內部類)

        1.沒有使用static修飾的內部類。
        2.在成員內部類中不允許出現靜態變數和靜態方法的宣告。
            static只能用在靜態常量的宣告上。
        3.成員內部類中可以訪問外部類中所有的成員(變數,方法),包含私有成員,如果在內部類中定義有和外部類同名的例項變數,訪問:
            OuterClass.this.outerMember;
        4.構建內部類的例項,要求必須外部類的例項先存在
            外部類的外部/外部類的靜態方法:new Outer().new Inner();
            外部類的例項方法:
                new Inner();

                this.new Inner();

**
 * @author gress
 * 例項內部類
 *
 */
class MemberOuter{
	
	private String s1 = "Outer InstanceMar";
	private String s2 = "OuterStatic s2";
	public void setS1(String s1) {
		this.s1 = s1;
		new MemberOuter().new MemberInner();
		this.new MemberInner();  //此時MemberOuter已經例項化完成,所以可以使用this
		new MemberInner().test2();
	}
	public static void  test2 (){
		new MemberOuter().new MemberInner();
		/*this.new MemberInner();  
		 * 此時MemberOuter沒有例項化完成,所以不可以使用this
		 * static 是在MemberOuter構造器前使用,所以此時this不能使用
		 * 
*/
		
	}


	class MemberInner{
		 String s1= "Inner  instanceMae  ";
		static final String s4 = "static final  MemberInner";
			
				void test2(){
					System.out.println(" s1 =" + s1);
					System.out.println(" Outter MemberOuter.this.s1 =" + MemberOuter.this.s1);
					System.out.println("s2 = "+s2);
				}
	}
	
}

public class MemberInnerTest {

	public static void main (String args []){
	/*	MemberOuter.MemberInner mm =  new MemberOuter().new MemberInner();
		mm.test2();*/
		
		MemberOuter mo = new MemberOuter();
		mo.setS1("");
		
		
	}
}


    3.區域性內部類:

        1.定義在方法體,甚至比方法體更小的程式碼塊中
        2.類比區域性變數。
        3.區域性內部類是所有內部類中最少使用的一種形式。
        4.區域性內部類可以訪問的外部類的成員根據所在方法體不同。
            如果在靜態方法中:
                可以訪問外部類中所有靜態成員,包含私有
            如果在例項方法中:
                可以訪問外部類中所有的成員,包含私有。
          區域性內部類可以訪問所在方法中定義的區域性變數,但是要求區域性變數必須使用final修飾。
          
**
 * @author gress 區域性內部類
 *
 */
public class LocalInnerTest {

	private int a = 1;
	private static int b = 2;

	public void test() {
		final int c = 3;
		class LocalInner {
			public void add1() {
				System.out.println("a= " + a);
				System.out.println("b= " + b);
				System.out.println("c= " + c);
			}
		}
		new LocalInner().add1();
	}

	static public void test2() {
		final int d = 5;
		class LocalInner2 {
			public void add1() {
				// System.out.println("a= " + a);
				System.out.println("b= " + b);
				System.out.println("c= " + d);
			}
		}
		new LocalInner2().add1();
	}

	public static void main(String args[]) {

		// LocalInnerTest() lc = new LocalInnerTest();
		new LocalInnerTest().test2();
		new LocalInnerTest().test();
	}
}


    4.匿名內部類

        1.沒有名字的區域性內部類。
        2.沒有class,interface,implements,extends關鍵字
        3.沒有構造器。
        4.一般隱式的繼承某一個父類或者實現某一個介面
        5.吃貨老師講的一個很生動的例子
        /**
         * @author gress 匿名內部類,我只會使用一次的類
         * 假如我想吃一個泡麵,但我不可能建一個廠,製造一個流水線,生產一包泡麵之後就在也不去使用這個泡麵廠了
         * 所以這裡引申出匿名內部類 ,而我們建立的泡麵廠就像這裡構建的一個類Pencil 鉛筆類一樣
         */
**
 * @author gress 匿名內部類,我只會使用一次的類
 * 
 * 就假如我想吃一個泡麵,但我不可能建一個廠,製造一個流水線,生產一包泡麵之後就在也不去使用這個泡麵廠了
 * 所以這裡引申出匿名內部類 ,而我們建立的泡麵廠就像這裡構建的一個類Pencil 鉛筆類一樣
 */
interface Pen {
	public void write();
}

class  Pencil implements Pen {
	@Override
	public void write() {
		//鉛筆 的工廠
	}
}

class Person {
	public void user(Pen pen) {
		pen.write();
	}
}

public class AnyInnerTest {
	public static void main(String args[]) {
		Person guo = new Person();
		
		guo.user(new Pen() {
			@Override
			public void write() {
				System.out.println("寫子");
			}
		});
	}

}



二: abstract  只能單繼承

    1.方法:抽象方法
      不能有方法體
      抽象方法所在類一定是抽象類
      抽象方法存在就是被覆蓋的,如果子類繼承帶有抽象方法的抽象類,必須對所以的抽象方法進行覆蓋
      
    2.類 :抽象類
      抽象類不能被例項化
      抽象類是對類的抽象,抽象所具有的共有特徵和行為
      抽象類所存在的目的就是用來被繼承,實現程式碼的複用
      抽象類可以有抽象方法也可以沒有抽象方法,可以像普通的一個類具有成員變數和方法
      如果一個類繼承抽象類,必須實現抽象父類的抽象方法,或者子類也是一個抽象方法

三: interface  可以多實現(繼承)

    1.介面是比抽象類還抽象的存在,介面是抽象類的極致抽象。
    2.介面中所有的方法都是public abstracht,介面中所有的變數都是public static final
    3.介面主要用來定義標準。
    4.介面可以多繼承。一個類可以實現多個介面。
    5.介面的存在本身可以規避java不能多繼承的操作特點。
    interface USBDevice{
    String type="USB";
        void driver();
    }
    
    class Mouse{
        select();
    }
    class USBMouse extends Mouse implements USBDevice{

    }
    
    class Computer{
        void use(USBDevice usb){
            usb.driver();
        }
    }