1. 程式人生 > >java外部類與內部類的關係

java外部類與內部類的關係

private,public,protected,default的訪問許可權區別

在學習外部類與內部類之前我們首先要弄明白private,public,protected,default在訪問許可權上有什麼不同,這對我們之後的理解會有一定的幫助。
1、private:訪問許可權最低的訪問控制符,被它修飾的變數只能訪問本類的物件。
2、public:訪問許可權最高,不僅是本類,子類,本包,其他的包,都可以去訪問它修飾的物件。
3、default:訪問許可權限制在本類以及本包內。
4、protected:訪問的範圍是本類,本包內,子類,但別的包不可以訪問。

外部類訪問內部類

在外部類的main方法中建立了外部類的物件,並通過它建立了內部類的物件,並呼叫了內部類的方法,這裡我們觀察呼叫時,age變數的變化。

public class People {	
	         private String name;
	         private int age=20;
	         private int ID ;	     	     
	         public static void main(String[] args){
		    	 People p = new People();
		    	 People.Student s = p.new Student();
		    	 s.study();	    	 
	     }	    	
	    class Student {
		    	private String name;
		    	private int age=18;
		    	private int studentNumber;
	    		public void study(){
		    		System.out.println("輸出age"+age);
		    		System.out.println("內部類變數"+this.age);
		    		System.out.println("外部類變數"+People.this.age);			    		
	    	}	    	    	
	    }		
}

輸出結果:
輸出age18、內部類變數18、外部類變數20
經測試,我們可以發現內部類物件不能直接獲得,只能由外部類的物件獲取。並且我們通過輸出結果,可以發現當外部類和內部類有相同屬性時,在內部類中會優先輸出內部類的屬性,只有通過外部類的物件來呼叫age屬性,才會在本例中輸出20。在內部類中,使用this,可以獲取內部類的屬性。

區域性內部類

這時候,我們轉變一下思路,索性把Student類的建立放在People類的方法裡,再看看結果會怎麼樣。

public class People {	
	       private String name;
	       private int age=20;
	       private int ID ;	          
	       public static void main(String[] args){
		       People p = new People();
		       class Student {
			       private String name;
			       private int age=18;
			       private int studentNumber;	    	
		  	       public void study(){
		  	       System.out.println("輸出age"+age);
		               System.out.println("內部類變數"+this.age);
		  	       System.out.println("外部類變數"+p.age);			    		
	    	   }	 
	        }
	        new Student().study();
	    }
}

輸出結構和之前是一樣的,這也不奇怪,我們只是把類在方法裡定義了,我們可以聯想到區域性變數的定義,只能在本方法中使用,那麼,方法內的類自然也只是屬於這個方法,訪問許可權只限於方法內。

靜態巢狀類

既然開始了我們就不停下探索的腳步,我們把內部類變成靜態類,我們可以理解為,這個內部類現在屬於外部類了,外部類可以通過類名來呼叫這個類並建立物件,毫無疑問,結果是輸出18。

public class People {
	     private String name;
	     private int age=20;
	     private int ID ;	     	     
	     public static void main(String[] args){
		     People p = new People();	    	 
		     new People.Student().study();	    	 
	     }	    	
	    static class Student {
		    private String name;
		    private int age=18;
		    private int studentNumber;
	            public void study(){
			    System.out.println("輸出age"+age);
			    System.out.println("內部類變數"+this.age);  			    		
	    	}	    	    	
	    }
}

匿名內部類

匿名內部類的實現涉及到了抽象類的實現,那麼什麼是抽象類呢?抽象類擁有一系列抽象的屬性或者方法,它本身不能new物件,只有在它被繼承並被重寫所有抽象方法之後才能得到實現。我們這次要通過建立一個匿名內部類的物件來使得一個抽象的類得到實體化並執行一系列方法。首先我們需要建立一個抽象類,然後再寫一個類建立匿名內部類的物件實現抽象類的方法(此處我們沒有用到繼承)。

abstract class People {	
	     private String name;
	     private int age=20;
	     private int ID ;	     	     
	     public abstract void work();    
}
 public class Test{	   	   
	     public static void main(String[] args){	    	  
		     Test t = new Test();
		      t.test(new People(){
		      public void work(){
		      System.out.println("我在工作");
	        	}
	         });
	      }	        
	       public void test(People people){
		         people.work();
		}			
}	

這段程式碼的關鍵部分在:

 t.test(new People(){
		      public void work(){
		      System.out.println("我在工作");
	        	}
	         });

似乎我們new了一個抽象類People的物件,但其實我們通過了匿名內部類來實現People類的例項化,它實現了work()抽象方法,然後呼叫此方法,輸出“我在工作”。