1.成員内部類
1.樣例
class OutClass {
class InnerClass {
public String SayHi() {
return "你好";
}
}
}
2.特點
- 内部類能夠無條件的通路外部類的成員變量,外部類要通路内部類成員變量需要使用new。
- 内部類和外部類有相同名稱的變量或者是方法,通路外部類方式為:外部類.this.方法。
- 内部類是依賴外部類的,隻有先有外部類才能有内部類。調用内部類方法為:
OutClass out = new OutClass();
OutClass.InnerClass inner = out.new InnerClass();
- 内部類的權限可以public,protected,保護類型和private。而外部類隻能是public和保護類型。
- 成員内部類不能存在static關鍵字,非靜态内部類也可以定義靜态成員但需要同時有final關鍵詞修飾。
2.局部内部類
public class Outer {
private int s = 100;
private int out_i = 1;
public void f(final int k) {
final int s = 200;
int i = 1;
final int j = 10;
// 定義在方法内部
class Inner {
int s = 300;// 可以定義與外部類同名的變量
// static int m = 20;//不可以定義靜态變量
Inner(int k) {
inner_f(k);
}
int inner_i = 100;
void inner_f(int k) {
// 如果内部類沒有與外部類同名的變量,在内部類中可以直接通路外部類的執行個體變量
System.out.println(out_i);
// 可以通路外部類的局部變量(即方法内的變量),但是變量必須是final的
System.out.println(j);
// System.out.println(i);
// 如果内部類中有與外部類同名的變量,直接用變量名通路的是内部類的變量
System.out.println(s);
// 用this.變量名通路的也是内部類變量
System.out.println(this.s);
// 用外部類名.this.内部類變量名通路的是外部類變量
System.out.println(Outer.this.s);
}
}
new Inner(k);
}
public static void main(String[] args) {
// 通路局部内部類必須先有外部類對象
Outer out = new Outer();
out.f(3);
}
}
是指内部類定義在一個類的方法,代碼塊中。
- 局部内部類隻能在代碼代碼塊、方法體内和作用域中使用(如建立對象和使用類對象等)
- 局部内部類通路作用域内的局部變量,該局部變量需要使用final修飾。
- 可以使用abstract修飾,聲明為抽象類。
- 隻能在定義該類的方法中執行個體化。
3.靜态内部類
public class Outer {
private static int i = 1;
private int j = 10;
public static void outer_f1() {}
public void outer_f2() {}
// 靜态内部類可以用public,protected,private修飾
// 靜态内部類中可以定義靜态或者非靜态的成員
private static class Inner {
static int inner_i = 100;
int inner_j = 200;
static void inner_f1() {
// 靜态内部類隻能通路外部類的靜态成員(包括靜态變量和靜态方法)
System.out.println("Outer.i" + i);
outer_f1();
}
void inner_f2() {
// 靜态内部類不能通路外部類的非靜态成員(包括非靜态變量和非靜态方法)
// System.out.println("Outer.i"+j);
// outer_f2();
}
}
public void outer_f3() {
// 外部類通路内部類的靜态成員:内部類.靜态成員
System.out.println(Inner.inner_i);
Inner.inner_f1();
// 外部類通路内部類的非靜态成員:執行個體化内部類即可
Inner inner = new Inner();
inner.inner_f2();
}
public static void main(String[] args) {
new Outer().outer_f3();
}
}
使用static修飾的内部類。
- 不依賴外部類,不能使用外部類非靜态的變量和方法。
- 不需要如成員内部類一樣,生成外部類對象來生成内部類。
- 靜态内部類中可以定義靜态或者非靜态的成員。
- 外部類通路内部類的靜态成員:内部類.靜态成員。
- 外部類通路内部類的非靜态成員:執行個體化内部類即可。
- 可以有非靜态的方法或者變量。
3.使用場景
- 當外部需要使用内部類而内部類不依賴與外部類的資源。
- 能夠單獨生成對象。
- 節省資源。
4.匿名内部類
就是沒有名字的内部類。匿名内部類的格式:
new 接口或父類(){
重寫抽象方法
};
2.應用場景
個人了解就是沒有實作一個接口,但是想重寫接口中的方法并且調用并傳回。
目的:
- 可以使命名變得簡潔。
- 使代碼更加緊湊,簡潔,封裝性比内部類更優。
- 一個類用于繼承其他類或是實作接口,無需增加其他的方法,隻是對繼承方法實作 覆寫。
public class OuterClass {
public InnerClass getInnerClass(final int num,String str2){
return new InnerClass(){
int number = num + 3;
public int getNumber(){
return number;
}
}; /* 分号不能省 */
}
public static void main(String[] args) {
OuterClass out = new OuterClass();
InnerClass inner = out.getInnerClass(2, "chenssy");
System.out.println(inner.getNumber());
}
}
interface InnerClass {
int getNumber();
}
----------------
Output:
5
如果不适用匿名内部類
interface InnerClass {
int getNumber(int a);
}
class InnerClassImpl{
int getNumber(int a){
system.out.print(a);}
}
InnerClass InnerClass = new InnerClassImpl();
使用匿名内部類之後
InnerClass InnerClass = new InnerClass (){
public int getNumber(int a){
return a;
}
}
特點:
- 匿名内部類是沒有通路修飾符的。
- new 匿名内部類,這個類首先是要存在的。如果我們将那個InnerClass接口注釋掉,就會出現編譯出錯。
- 注意getInnerClass()方法的形參,第一個形參是用final修飾的,而第二個卻沒有。同時我們也發現第二個形參在匿名内部類中沒有使用過,是以當所在方法的形參需要被匿名内部類使用,那麼這個形參就必須為final。
- 匿名内部類是唯一一種沒有構造方法的類。
- 匿名内部類不能定義任何靜态成員、方法和類。
5.使用内部類的原因:
- 可以實作多重繼承。(不同的内部類可以繼承不同的類)。
- 内部類可以更好的隐藏。
- 當我們不想寫接口的實作或隻是用一次對象時可以使用匿名内部類。
- 每個内部類都是一個單獨的個體。