java靜態內部類瞭解一下

1. java內部類

什麼是內部類?將一個類的定義放在另一個類的內部,就是內部類。Java的內部類主要分爲成員內部類、局部內部類、匿名內部類、靜態內部類。

public class 外部類的名稱{
    //外部類的成員
    public class 內部類的名稱{
             //內部類的成員
    }
}

內部類的作用;
1)實現多重繼承;
2)內部類可以很好的實現隱藏:一般的非內部類,是不允許有 private 與protected權限的,但內部類可以
3)減少了類文件編譯後的產生的字節碼文件的大小

注意:內部類在編譯完成後也會產生.class文件,但文件名稱是:外部類名稱$內部類名稱.class
內部類的種類:成員內部類、靜態內部類、局部內部類、匿名內部類。

1.1 成員內部類

1、成員內部類是最普通的內部類,就是一個普通的類定義在另一個類的內部,也叫實例內部類。應用場合:每一個外部類對象都需要一個內部類的實例,內部類離不開外部類存在(相當於心臟對人體)

2、成員內部類的特徵:

  • 作爲外部類的一個成員存在,與外部類的屬性、方法並列
  • 成員內部類持有外部類的引用
  • 成員內部類中不能定義static變量和方法

示例1:

public class StaticInnerClass {
	public static void main(String[] args){
		Body body=new Body("兩個胳膊","兩條腿","血");
        Body.Heart  heart=body.new Heart();
        heart.work();
	}
	
}


class Body {
    String arm;
    String leg;
    String blood;
    public Body(String arm, String leg, String blood) {
       super();
       this.arm = arm;
       this.leg = leg;
       this.blood = blood;
    }
    
    //成員內部類Heart
    class Heart{
        String name;
         void work() {
            System.out.println("心臟正在給"+arm+leg+"輸"+blood);
        }
     }
}

運行:

心臟正在給兩個胳膊兩條腿輸血

示例2:

public class StaticInnerClass {
	public static void main(String[] args){
		Outer outer=new Outer();
        outer.print();//調用外部類的方法
	}
	
}


class Outer {

    private String name="Hello World";
    
    public class Inner{ 	
        public void print(){
            System.out.println(name);  //內部類調用外部類屬性
        }
    }
    
    public void print(){  //定義外部類方法
        new Inner().print();//通過內部類的實例化對象調用方法
    }
      
       
}

運行:

Hello World
1.2 靜態內部類

1、內部類如果使用static聲明,則此內部類就稱爲靜態內部類。(其實也相當於外部類)可以通過外部類 . 內部類來訪問。
2、靜態內部類使用場合:內部類不需要外部類的實例(注意區分成員內部類),靜態內部類存在僅僅爲外部類提供服務或者邏輯上屬於外部類,且邏輯上可以單獨存在。
3、靜態內部類的特徵:

  • 靜態內部類不會持有外部類的引用
  • 靜態內部類可以訪問外部的靜態變量,如果訪問外部類的成員變量必須通過外部類的實例訪問

4、Java中只有內部類纔可以是靜態的

使用格式:Outer.Inner inner = new Outer.Inner();

示例1:

public class StaticInnerClass {
	public static void main(String[] args){
		
		Company.Clear zcl=new Company.Clear();
        zcl.work("shen_hua");
	}
	
}


class Company {
	
    String companyNam;
    static String country;
    
    static class Clear{   // 靜態內部類
        String name;
        
       //無參數的構造函數
        public Clear() {    
            // TODO Auto-generated constructor stub
        	System.out.println("無參對象初始化");
        }       
        
       //帶參數的構造函數
        public Clear(String name) {  
            super();
            this.name = name;
        }
        
        // 內部類的非靜態方法
        public void work(String name){
            String na=new Company().companyNam="聯想";   // 靜態內部類實例化外部類,調用外部類的非靜態屬性
            country="中國";								// 內部類訪問外部靜態屬性
            System.out.println(name+"爲"+na+"打掃衛生,該公司屬於"+country);
        }
    }
    
}


運行:

無參對象初始化
shen_hua爲聯想打掃衛生,該公司屬於中國

示例2:

public class StaticInnerClass {
	
	public static void main(String[] args){
		  Outer.Inner inner=new Outer.Inner();
	      inner.show();	
	}
	
}


class Outer {
    private static String info="Hello World";
    private int i=8;
    
    static class Inner{
        int num=new Outer().i; //通過新建外部類獲取外部類的非靜態成員變量,而靜態成員變量可以直接使用
        public  void show() {
            System.out.println(info+"---"+num);
        }
    };
}

運行:

Hello World---8
1.3 局部內部類

1、局部內部類也叫區域內嵌類,局部內部類與成員內部類類似,不過,區域內嵌類是定義在一個方法中的內嵌類。
2、使用場合:如果內部類對象僅僅爲外部類的某個方法使用,使用局部內部類
3、特徵:

  • 用在方法內部,作用範圍僅限於該方法中
  • 根據情況決定持有外部類對象引用
  • 不能使用private,protected,public修飾符
  • 不能包含靜態成員
public class StaticInnerClass {
	
	public static void main(String[] args){
		 School qinghua=new School("清華","互聯網培訓",1000);	        
	     qinghua.show();
	}	
}


class School {

    String schoolName;
    String buss="培養人才";
    int studentNum;
    
    public School() {
        // TODO Auto-generated constructor stub
    }
    
    public School(String schoolName, String buss, int studentNum) {
        super();
        this.schoolName = schoolName;
        this.buss = buss;
        this.studentNum = studentNum;
    }

    // 成員方法:宣傳
    public void show(){
        final double tvMoney=10000;
        final double netMoney=20000;
        // 局部內部類
        class AdverTeam{
            String teamName="shen_hua";  
            
            public void tvShow(){   //電視宣傳
                System.out.println("宣傳隊是:"+teamName);
                System.out.println("這是電視宣傳,學校名稱"+schoolName+",業務內容:"+buss+",學校人數:"+studentNum+",宣傳所需費用"+tvMoney);
            }
            
            public void netShow(){  //網絡宣傳
                System.out.println("宣傳隊是:"+teamName);
                System.out.println("這是網絡宣傳,學校名稱"+schoolName+",業務內容:"+buss+",學校人數:"+studentNum+",宣傳所需費用"+netMoney);
            }
        }
        
        new AdverTeam().tvShow();  //新建局部類,並調用局部類的方法
        new AdverTeam().netShow();
    }
}

運行:

宣傳隊是:shen_hua
這是電視宣傳,學校名稱清華,業務內容:互聯網培訓,學校人數:1000,宣傳所需費用10000.0
宣傳隊是:shen_hua
這是網絡宣傳,學校名稱清華,業務內容:互聯網培訓,學校人數:1000,宣傳所需費用20000.0
1.5 匿名內部類

1、如果一個內部類在整個操作中只使用一次的話,就可以定義爲匿名內部類。匿名內部類也就是沒有名字的內部類,這是java爲了方便我們編寫程序而設計的一個機制,因爲有時候有的內部類只需要創建一個它的對象就可以了,以後再不會用到這個類,這時候使用匿名內部類就比較合適。
2、使用場合:簡化內部類的使用
3、特徵:

  • 使用new創建 ,沒有具體位置
  • 創建的匿名類,默認繼承或實現new後面的類型
  • 根據使用情況決定是否持有外部類對象引用
  • 內嵌匿名類編譯後生成的.class文件的命名方式是”外部類名稱$編號.class”,編號爲1,2,3…n,編號爲x的文件對應的就是第x個匿名類
public class StaticInnerClass {
	
	public static void main(String[] args){
		
		Person p=new Person() { 
			
            public void run() {
                System.out.println("匿名內部類實現的");
            }
        };
        p.run();
    }
}	



interface Person {
    public void run();
}

運行:

匿名內部類實現的

2. 另一個學習示例 :

package test;

public class StaticInnerClass {

		public static void main(String[] args){			
			Mother mother=new Mother("lucy");  //實例化母親
			mother.getAge();
			mother.eat("蘋果");                //實例調用非靜態方法
			new Mother().motherTest1();              // 非靜態方法的類調用形式必須是new XXX().XXX()形式調用
			Mother.motherTest2();              // 靜態方法的類調用的形式可以直接用類名.XXX()或new XXX().XXX()調用
						
			
			Mother.Baby baby=new Mother.Baby(); 
			Mother.Baby.eat();             // 內部靜態類中的類調用靜態方法
			baby.eat();					   // 內部靜態類中的實例調用靜態方法
			new Mother.Baby().childTest1();// 內部靜態類中的非靜態方法調用
			baby.childTest1();             // 內部靜態類中的非靜態方法調用
			baby.childTest2();            // 內部靜態類新建外部類對象
						
		}

}


class Mother
{
	    //定義一個實例變量和一個靜態變量
		private String name;
		private int age;             // 私有變量,在類的外部不能訪問
		private static  String food;
		private  String fruit;//母親吃的食物
		
		public Mother(){              // 空參構造函數		
			food="米飯";
		}
		public Mother(String name){   // 帶參構造函數
			this.name=name;
			
		}
	 
		public String getName(){     //定義非靜態方法
			return this.name;
		}
		
		public void setName(String name){
			this.name=name;
		}
			
		public void eat(String fruit)  {
			this.fruit=fruit;
			System.out.println(this.name+" 吃了 "+this.fruit);			
		}
		
		
		public void getAge(){      //定義非靜態方法,外部類對象可以直接私有變量
			age=20;
			System.out.println("年齡:"+age);
		}
		
		public void motherTest1(){      //定義非靜態方法	(實例方法)	
			System.out.println("非靜態方法調用靜態變量:"+food);
			System.out.println("類調用非靜態方法");
		}
		
		public static void motherTest2(){      //定義靜態方法		
			System.out.println("類調用靜態方法");
		}
		
		public static void motherdo(){     //靜態方法調用靜態變量
			System.out.println("母親在吃"+food);
		}
		
		// 內部靜態類
		static class Baby{   	
			
			static String childfood;   // 在靜態內部類中定義一個靜態變量
			int dd;          // 一個實例變量
			
			
		    {                //定義一個匿名代碼塊
		    	System.out.println("我在匿名代碼塊裏。。");  
		    }      
		    
		    static{         //一個靜態代碼塊
		    	System.out.println("我在靜態代碼塊裏。。");  
		    }  
		    
		    public static void run(){    // 非靜態方法調用
		    	System.out.println("孩子在奔跑。。");  
		    }
		    
			public static void eat(){  
				System.out.println("孩子從母親吃的 "+ food +" 中吸收營養");
			}
			
			public void childTest1(){	
				
				//dd=age;     								 //在靜態內部類中調用外部類的非靜態屬性編譯出錯
				childfood=food;	
				System.out.println("childfood:"+childfood);   //在靜態內部類中調用外部類的靜態屬性
				motherdo();									  //可以直接調用外部類的靜態方法
				//motherTest1();								 //在靜態內部類中調用外部類的非靜態方法編譯出錯
			}	
				
			public void childTest2(){	
				Mother mm=new Mother();
				dd=mm.age;				
				mm.motherTest1();                          //可以通過創建外部類實例來調用外部類的非靜態方法
				System.out.println("內部類:"+dd);           //可以通過創建外部類實例來調用外部類的非靜態屬性
				                       
			}				
			
		}
	
}

運行:

年齡:20
lucy 吃了 蘋果
非靜態方法調用靜態變量:米飯
類調用非靜態方法
類調用靜態方法
我在靜態代碼塊裏。。
我在匿名代碼塊裏。。
孩子從母親吃的 米飯 中吸收營養
孩子從母親吃的 米飯 中吸收營養
我在匿名代碼塊裏。。
childfood:米飯
母親在吃米飯
childfood:米飯
母親在吃米飯
非靜態方法調用靜態變量:米飯
類調用非靜態方法
內部類:0

總結:
1、靜態內部類中可以寫哪些內容

  • 匿名代碼塊
  • 靜態代碼塊
  • 靜態變量和非靜態變量
  • 靜態方法和非靜態方法
    注意:不能在靜態內部類中寫抽象方法

2、外部類如何調用靜態內部類中的屬性和方法

  • 外部類可以通過創建靜態內部類實例的方法來調用靜態內部類的非靜態屬性和方法
  • 外部類可以直接通過“ 外部類.內部類.屬性(方法)” 的方式直接調用靜態內部類中的靜態屬性和方法

3、靜態內部類如何調用外部類的屬性和方法

  • 靜態內部類可以直接調用外部類的靜態屬性和方法
  • 靜態內部類可以通過創建外部類實例的方法調用外部類的非靜態屬性和方法

4、如何創建靜態內部類實例

  • 在非外部類中:外部類名.內部類名 name = new 外部類名.內部類名();
  • 在外部類中:內部類名 name = new 內部類名();

參考:
https://www.cnblogs.com/shen-hua/p/5440285.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章