java基礎學習-內部類

內部類

1.內部類可以很好的實現隱藏

一般的非內部類,是不允許有 private 與protected權限的,但內部類可以
平時我們對類的訪問權限,都是通過類前面的訪問修飾符來限制的,一般的非內部類,是不允許有 private 與protected權限的,但內部類可以,所以我們能通過內部類來隱藏我們的信息。可以看下面的例子

接口
package insidecategory;
public interface Incrementable{
 void increment();
}
具體類
package insidecategory;
public class Example {
  
   <strong> private class InsideClass implements InterfaceTest{
         public void test(){
             System.out.println("這是一個測試");
         }
    }</strong>
    public InterfaceTest getIn(){
        return new InsideClass();
    }
}
上面加粗的部分是內部類,訪問修飾符是private
客戶端程序
package insidecategory;
public class TestExample {
 public static void main(String args[]){
    Example a=new Example();
    <strong>InterfaceTest a1=a.getIn();</strong>
    a1.test();
 }
}
加粗的那部分就是客戶端調用的代碼,從這段代碼裏面我只知道Example的
getIn()方法能返回一個InterfaceTest 實例但我並不知道這個實例是這麼實現的。而且由於InsideClass 是private的,所以我們如果不看代碼的話根本看不到這個具體類的名字,所以說它可以很好的實現隱藏。

2.內部類擁有外圍類的所有元素的訪問權限

3.可是實現多重繼承

這個特點非常重要,個人認爲它是內部類存在的最大理由之一。正是由於他的存在使得Java的繼承機制更加完善。大家都知道Java只能繼承一個類,它的多重繼承在我們沒有學習內部類之前是用接口來實現的。但使用接口有時候有很多不方便的地方。比如我們實現一個接口就必須實現它裏面的所有方法。而有了內部類就不一樣了。它可以使我們的類繼承多個具體類或抽象類。大家看下面的例子。
類一
package insidecategory;
public class Example1 {
   public String name(){
       return "liutao";
   }
}
類二
package insidecategory;
public class Example2 {
    public int age(){
        return 25;
    }
}
類三
package insidecategory;
public class MainExample{
   private class test1 extends Example1{
        public String name(){
          return super.name();
        }
    }
    private class test2 extends Example2{
       public int age(){
         return super.age();
       }
    }
   public String name(){
    return new test1().name();
   }
   public int age(){
       return new test2().age();
   }
   public static void main(String args[]){
       MainExample mi=new MainExample();
       System.out.println("姓名:"+mi.name());
       System.out.println("年齡:"+mi.age());
   }
}
大家注意看類三,裏面分別實現了兩個內部類 test1,和test2 ,test1類又繼承了Example1,test2繼承了Example2,這樣我們的類三MainExample就擁有了Example1和Example2的方法和屬性,也就間接地實現了多繼承。

4.可以避免修改接口而實現同一個類中兩種同名方法的調用。

大家假想一下如果,你的類要繼承一個類,還要實現一個接口,可是你發覺你繼承的類和接口裏面有兩個同名的方法怎麼辦?你怎麼區分它們??這就需要我們的內部類了。看下面的代碼
接口
package insidecategory;
public interface Incrementable{
 void <strong>increment</strong>();
}
 
類 MyIncrement
package insidecategory;
public class MyIncrement {
    public void <strong>increment</strong>(){
      System.out.println("Other increment()");
    }
    static void f(MyIncrement f){
        f.increment();
    }
 
}
大家看上面加黑的部分,兩個方法都是一樣的。在看下面這個類要繼承這兩個類
如果不用內部類
package insidecategory;
public class Callee2 extends MyIncrement implements Incrementable{
public void increment(){
        //代碼
       }
}
想問一下大家increment()這個方法是屬於覆蓋MyIncrement這裏的方法呢?還是Incrementable這裏的方法。我怎麼能調到MyIncrement這裏的方法?顯然這是不好區分的。而我們如果用內部類就很好解決這一問題了。看下面代碼
package insidecategory;
public class Callee2 extends MyIncrement{
 private int i=0;
 private void incr(){
       i++;
       System.out.println(i);
 }
 private class Closure implements Incrementable{
      public void increment(){
        incr();
      }
 }
 Incrementable getCallbackReference(){
      return new Closure();
 }
}
我們可以用內部類來實現接口,這樣就不會與外圍類的方法衝突了。

內部類分類

1.成員內部類

成員內部類(member inner class):可以訪問外部類的靜態與非靜態的方法與成員變量。生成成員內部類對象的方式爲: 
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
class MemberInner{
	private int a = 4;	
	public class Inner2{
		private int a = 5;		
		public void doSomething(){
			System.out.println(MemberInner.this.a);
		}
	}
	
	public void method(){
		Inner2 inner = this.new Inner2();
	}
}

public class MemberInnerClassTest{
	public static void main(String[] args){
		MemberInner.Inner2 inner = (new MemberInner()).new Inner2();		
		inner.doSomething();		
	}
}

2.靜態內部類

 靜態內部類(static inner class):只能訪問外部類的靜態成員變量與靜態方法,生成靜態內部類對象的方式爲: 
OuterClass.InnerClass inner = new OuterClass.InnerClass();
class StaticInner{ 
	private static int a = 4;
	public static class Inner	{
		public void test(){
			System.out.println(a);
		}
	}
}

public class StaticInnerClassTest{
	public static void main(String[] args){
		StaticInner.Inner inner = new StaticInner.Inner();		
		inner.test();
	}
}

3.局部內部類

局部內部類(Local Inner Class):定義在方法當中,只能訪問方法中聲明的final類型的變量,無法在外部直接使用。
public class Parcel4 { 
    public Destination destination(String s) { 
        class PDestination implements Destination { 
            private String label; 
 
            private PDestination(String whereTo) { 
                label = whereTo; 
            } 
 
            public String readLabel() { 
                return label; 
            } 
        } 
        return new PDestination(s); 
    } 
 
    public static void main(String[] args) { 
        Parcel4 p = new Parcel4(); 
        Destination d = p.destination("Tasmania"); 
    } 
}

4.匿名內部類

匿名內部類(Anonymous Inner Class):匿名內部類會隱式地繼承一個父類或實現一個接口。
public static void main(String[] args){
		AnonymousInnerClassTest test = new AnonymousInnerClassTest();
		//String str = test.get(new Date());;
		//System.out.println(str);
		String str = test.get(new Date(){ 
			public String toLocaleString(){
				return "hello world";
			}
		});
		System.out.println(str);
}




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