java 四種內部類區別
阿新 • • 發佈:2018-12-26
Java中的內部類共分為四種:
靜態內部類static inner class (also called nested class)
成員內部類member inner class
區域性內部類local inner class
匿名內部類anonymous inner class
靜態內部類Static Inner Class
最簡單的內部類形式。
類定義時加上static關鍵字。
不能和外部類有相同的名字。
被編譯成一個完全獨立的.class檔案,名稱為OuterClass$InnerClass.class的形式。
只可以訪問外部類的靜態成員和靜態方法,包括了私有的靜態成員和方法。
生成靜態內部類物件的方式為:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
示例程式碼:
package com.learnjava.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();
}
}
成員內部類 Member Inner Class
成員內部類也是定義在另一個類中,但是定義時不用static修飾。
成員內部類和靜態內部類可以類比為非靜態的成員變數和靜態的成員變數。
成員內部類就像一個例項變數。
它可以訪問它的外部類的所有成員變數和方法,不管是靜態的還是非靜態的都可以。
在外部類裡面建立成員內部類的例項:
this.new Innerclass();
在外部類之外建立內部類的例項:
(new Outerclass()).new Innerclass();
在內部類裡訪問外部類的成員:
Outerclass.this.member
示例程式碼:
package com.learnjava.innerclass;
class MemberInner
{
private int d = 1;
private int a = 2;
// 定義一個成員內部類
public class Inner2
{
private int a = 8;
public void doSomething()
{
// 直接訪問外部類物件
System.out.println(d);
System.out.println(a);// 直接訪問a,則訪問的是內部類裡的a
// 如何訪問到外部類裡的a呢?
System.out.println(MemberInner.this.a);
}
}
}
public class MemberInnerClassTest
{
public static void main(String[] args)
{
// 建立成員內部類的物件
// 需要先建立外部類的例項
MemberInner.Inner2 inner = new MemberInner().new Inner2();
inner.doSomething();
}
}
匿名內部類Anonymous Inner Class
匿名內部類就是沒有名字的區域性內部類,不使用關鍵字class, extends, implements, 沒有構造方法。
匿名內部類隱式地繼承了一個父類或者實現了一個介面。
匿名內部類使用得比較多,通常是作為一個方法引數。
生成的.class檔案中,匿名類會生成OuterClass$1.class檔案,數字根據是第幾個匿名類而類推。
示例程式碼:
package com.learnjava.innerclass;
import java.util.Date;
public class AnonymouseInnerClass
{
@SuppressWarnings("deprecation")
public String getDate(Date date)
{
return date.toLocaleString();
}
public static void main(String[] args)
{
AnonymouseInnerClass test = new AnonymouseInnerClass();
// 列印日期:
String str = test.getDate(new Date());
System.out.println(str);
System.out.println("----------------");
// 使用匿名內部類
String str2 = test.getDate(new Date()
{
});// 使用了花括號,但是不填入內容,執行結果和上面的完全一致
// 生成了一個繼承了Date類的子類的物件
System.out.println(str2);
System.out.println("----------------");
// 使用匿名內部類,並且重寫父類中的方法
String str3 = test.getDate(new Date()
{
// 重寫父類中的方法
@Override
@Deprecated
public String toLocaleString()
{
return "Hello: " + super.toLocaleString();
}
});
System.out.println(str3);
}
}
靜態內部類static inner class (also called nested class)
成員內部類member inner class
區域性內部類local inner class
匿名內部類anonymous inner class
靜態內部類Static Inner Class
最簡單的內部類形式。
類定義時加上static關鍵字。
不能和外部類有相同的名字。
被編譯成一個完全獨立的.class檔案,名稱為OuterClass$InnerClass.class的形式。
只可以訪問外部類的靜態成員和靜態方法,包括了私有的靜態成員和方法。
生成靜態內部類物件的方式為:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
示例程式碼:
package com.learnjava.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();
}
}
成員內部類 Member Inner Class
成員內部類也是定義在另一個類中,但是定義時不用static修飾。
成員內部類和靜態內部類可以類比為非靜態的成員變數和靜態的成員變數。
成員內部類就像一個例項變數。
它可以訪問它的外部類的所有成員變數和方法,不管是靜態的還是非靜態的都可以。
在外部類裡面建立成員內部類的例項:
this.new Innerclass();
在外部類之外建立內部類的例項:
(new Outerclass()).new Innerclass();
在內部類裡訪問外部類的成員:
Outerclass.this.member
示例程式碼:
package com.learnjava.innerclass;
class MemberInner
{
private int d = 1;
private int a = 2;
// 定義一個成員內部類
public class Inner2
{
private int a = 8;
public void doSomething()
{
// 直接訪問外部類物件
System.out.println(d);
System.out.println(a);// 直接訪問a,則訪問的是內部類裡的a
// 如何訪問到外部類裡的a呢?
System.out.println(MemberInner.this.a);
}
}
}
public class MemberInnerClassTest
{
public static void main(String[] args)
{
// 建立成員內部類的物件
// 需要先建立外部類的例項
MemberInner.Inner2 inner = new MemberInner().new Inner2();
inner.doSomething();
}
}
方法內部類 Local Inner Class
class Out
{
private int age
= 12 ;
public void Print( final int x)
{
class In
{
public void inPrint()
{
System.out.println(x);
System.out.println(age);
}
}
new In().inPrint();
}
}
public class Demo
{
public static void main(String[]
args) {
Out
out = new Out();
out.Print( 3 );
}
}
|
執行結果:
3
12
在上面的程式碼中,我們將內部類移到了外部類的方法中,然後在外部類的方法中再生成一個內部類物件去呼叫內部類方法
如果此時我們需要往外部類的方法中傳入引數,那麼外部類的方法形參必須使用final定義
至於final在這裡並沒有特殊含義,只是一種表示形式而已
匿名內部類Anonymous Inner Class
匿名內部類就是沒有名字的區域性內部類,不使用關鍵字class, extends, implements, 沒有構造方法。
匿名內部類隱式地繼承了一個父類或者實現了一個介面。
匿名內部類使用得比較多,通常是作為一個方法引數。
生成的.class檔案中,匿名類會生成OuterClass$1.class檔案,數字根據是第幾個匿名類而類推。
示例程式碼:
package com.learnjava.innerclass;
import java.util.Date;
public class AnonymouseInnerClass
{
@SuppressWarnings("deprecation")
public String getDate(Date date)
{
return date.toLocaleString();
}
public static void main(String[] args)
{
AnonymouseInnerClass test = new AnonymouseInnerClass();
// 列印日期:
String str = test.getDate(new Date());
System.out.println(str);
System.out.println("----------------");
// 使用匿名內部類
String str2 = test.getDate(new Date()
{
});// 使用了花括號,但是不填入內容,執行結果和上面的完全一致
// 生成了一個繼承了Date類的子類的物件
System.out.println(str2);
System.out.println("----------------");
// 使用匿名內部類,並且重寫父類中的方法
String str3 = test.getDate(new Date()
{
// 重寫父類中的方法
@Override
@Deprecated
public String toLocaleString()
{
return "Hello: " + super.toLocaleString();
}
});
System.out.println(str3);
}
}