內部類詳解(含java8新特性)
阿新 • • 發佈:2018-12-26
內部類的作用:
- 提供很好的封裝,不允許同一個包中的其他類訪問!
- 內部類成員能直接訪問外部類的私有資料
- 匿名內部類適用於建立僅僅需要使用一次的類
內部類分類:
- 非靜態內部類
- 靜態內部類(類內部類)
- 成員內部類
- 匿名內部類
非靜態內部類注意事項:
- 非靜態內部類的成員可訪問外部類的private成員,反過來不成立
—原因:外部類物件訪問非靜態內部類成員時,可能非靜態內部類物件根本不存在!而非靜態內部類物件訪問外部類成員時,外部類物件一定存在! - 不允許在外部類的靜態成員中直接使用非靜態內部類!
- 非靜態內部類裡不能有靜態方法,靜態成員變數,靜態初始化程式碼塊!
總之:就是一個先來後到問題,先有外部類,才能有非靜態內部類
靜態內部類注意事項:
- static修飾的,所以這個內部類屬於外部類本身,也叫類內部類!
- 靜態內部類可以包含靜態成員,也能包含非靜態成員,靜態成員不能訪問非靜態成員!(又是先來後到問題)
- java允許在介面中定義內部類,預設使用public static修飾!
區域性內部類
把一個內部類放在方法裡定義,這個內部類就是區域性內部類,僅在該方法裡有效!不能有訪問控制符和static修飾符!作用域是當前方法!很少使用!
注意事項:
- 只能用預設訪問修飾符
匿名內部類
建立那種只需要一次使用的類,必須繼承一個父類或者實現一個介面!
語法:
new 實現介面()|父類構造器(實參列表)
{
//匿名內部類的實體部分
}
匿名內部類不能是抽象類,不能定義構造器!
java8以前,java要求被區域性內部類,匿名內部類訪問的區域性變數必須使用final修飾,java8以後,這個限制取消了!
使用靜態內部類和非靜態內部類
宣告變數的語法完全一樣
格式:OuterClass.InnerClass varName
建立的時候有所區別:
非靜態內部類:必須使用外部類物件呼叫構造器
Out.In in=new out().new In();
靜態內部類:只需使用外部類就能呼叫構造器
StaticOut.StaticIn in=new StaticOut.StaticIn();
例項:
抽象類I,含有抽象方法getPrice()
public abstract class I {
public abstract double getPrice();
}
TestClass包含四種內部類!
public class TestClass {
//成員變數
private int i=0;
//成員方法
//I是一個抽象類,含有抽象方法
public void test1(I i){
System.out.println("成員方法");
}
//成員內部類Inner2,修飾符public
public class Inner2{
}
//成員內部類Inner3,修飾符protected
protected class Inner3{
}
//成員內部類Inner1,修飾符預設
class Inner1{
}
//成員內部類(就是作為外部類的成員)Inner,修飾符private
private class Inner{
}
//成員方法
public void test(){
//區域性內部類(內部類定義在方法和作用域內)
/*編譯器報錯,修飾符不能是public*/
public class Inner4{
}
//區域性內部類
/*編譯器報錯,修飾符不能是protected */
protected class Inner6{
}
//區域性內部類
class Inner5{
}
//區域性內部類
/*編譯器報錯,修飾符不能是private*/
private class Inner7{
}
}
//靜態內部類(static+成員內部類)
public static class Inner10{
}
protected static class Inner11{
}
static class Inner9{
}
private static class Inner8{
}
//匿名內部類
public static void main(String[] args) {
TestClass test2=new TestClass();
test2.test1(new I(){
@Override
public double getPrice() {
System.out.println("匿名內部類");
return 0;
}
});
}
}