內部類
內部類(inner class)是定義在另一個類中的類
內部類的好處:
|--1.隱藏機制:內部類封裝性更好,隱藏在一個類之中,同一包中的其他類也不能訪問
|--2.內部類可以訪問外圍類的私有數據
成員內部類
member inner class
可以訪問外部類的所有成員變量和方法(無論靜態、非靜態)
自身沒有靜態成員
|--外部類里面創建成員內部類的實例:this.new Innerclass();
|--在外部類之外創建內部類的實例:new Outerclass().new Innerclass();
|--在內部類里訪問外部類的成員:Outerclass.this.member
class Hero {
void callHorse() {
// 自己使用自己的成員內部類
System.out.print("呂布");
this.new Horse().show();
}
// 成員內部類
class Horse {
public void show() {
System.out.println("---赤兔---");
}
}
}
public class InnerClassMember {
public static void main(String[] args) {
Hero h = new Hero();
h.callHorse();
// 創建一個類的內部類
Hero.Horse horse = new Hero().new Horse();
horse.show();
}
}
呂布---赤兔---
---赤兔---
靜態內部類
static inner class (nested class)
使用內部類只是為了把一個類隱藏在另外一個類的內部,並不需要內部類引用外圍對象,可以將內部類聲明為static。
生成靜態內部類對象的方式為:
OuterClass.InnerClass inner = new OuterClass.InnerClass();// 里面的類不用new
|--成員內部類沒有靜態成員;
|--靜態內部類只能訪問外圍類的靜態成員
局部內部類
local inner class
在方法中定義、使用
不能被public, protected, private和static修飾(像局部變量一樣)
只能訪問方法中定義的final類型的局部變量(初始化之后便不能更改)
import java.util.*;
// 以集合排序需要實現Comparator接口為例
public class TestInnerClassLocal {
public static void main(String[] args) {
class InnerComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
}
// 需要先定義局部內部類,再使用
InnerComparator com = new InnerComparator();
List<Integer> lst = new ArrayList<>();
Collections.addAll(lst, 2, 3, 5, 1, 4);
Collections.sort(lst, com);
System.out.println(lst);
}
}
[5, 4, 3, 2, 1]
匿名內部類
anonymous inner class
沒有名字的局部內部類。
用於只創建這個類的一個對象的場合(不必命名),通常是作為方法的參數
隱式地繼承了一個父類或者實現了一個接口
限制:由於構造方法的名字與類名相同,而匿名類沒有類名,所以,匿名類不能有構造方法。
綜合代碼:
import java.util.Date;
class OutClass {
private static String field_Static = "外圍類:靜態變量";
private String field_Common = "外圍類:普通變量";
private static void methodStatic() {
System.out.println("外圍類:靜態方法");
}
private void methodCommon() {
System.out.println("外圍類:普通方法");
}
// 成員內部類
class InnerClassMember {
// Err:
// private static String inner_fieldStatic = "內部類:靜態變量";
private String inner_fieldCommon = "|---內部類:普通變量";
// Err:
// private static void innerMethodStatic() {}
private void innerMethodCommon() {
System.out.println("|---內部類:普通方法");
}
public void methodInner() {
// 變量·外
System.out.println(OutClass.this.field_Common);
System.out.println(field_Static);
// 變量·內
System.out.println(inner_fieldCommon);
// 方法·外
methodStatic();
OutClass.this.methodCommon();
// 方法·內
innerMethodCommon();
}
}
// 靜態內部類
static class InnerClassStatic {
private static String inner_fieldStatic = "|---靜態內部類:靜態變量";
private String inner_fieldCommon = "|---靜態內部類:普通變量";
private static void innerMethodStatic() {
System.out.println("|---靜態內部類:靜態方法");
}
private void innerMethodCommon() {
System.out.println("|---靜態內部類:普通方法");
}
public void methodInner() {
// 變量·外
System.out.println(OutClass.field_Static);
// 變量·內
System.out.println(inner_fieldCommon);
System.out.println(inner_fieldStatic);
// 方法·外
OutClass.methodStatic();
// 方法·內
innerMethodStatic();
innerMethodCommon();
}
}
// 局部內部類
public void method4InnerClassLocal() {
String localField = "局部變量";
final String localFieldFinal = "局部變量(final)";
// ↑Java 8中不用加final,但局部內部類中不能修改其值
// 局部內部類
class InnerClassLocal {
public void localClassM() {
// Err: System.out.println(localField);
System.out.println(localFieldFinal);
System.out.println(field_Common);
System.out.println(field_Static);
methodCommon();
methodStatic();
}
}
InnerClassLocal _local_in_c = new InnerClassLocal();
_local_in_c.localClassM();
}
// --------------------
public void testAnonymousClass() {
// 匿名內部類
PrintDate(new Date() {
public long getTime() {
System.out.println(field_Common);
System.out.println(field_Static);
methodCommon();
methodStatic();
return 10086;
}
});
}
private void PrintDate(Date dt) {
System.out.println(dt.getTime());
}
}
public class InnerClassTest1 {
public static void main(String[] args) {
System.out.println("===↓↓↓成員內部類===================");
OutClass.InnerClassMember ic = new OutClass().new InnerClassMember();
ic.methodInner();
System.out.println("===↓↓↓靜態內部類===================");
OutClass.InnerClassStatic ics = new OutClass.InnerClassStatic();
ics.methodInner();
System.out.println("===↓↓↓局部內部類===================");
OutClass oc = new OutClass();
oc.method4InnerClassLocal();
System.out.println("===↓↓↓匿名內部類===================");
oc.testAnonymousClass();
}
}
===↓↓↓成員內部類===================
外圍類:普通變量
外圍類:靜態變量
|---內部類:普通變量
外圍類:靜態方法
外圍類:普通方法
|---內部類:普通方法
===↓↓↓靜態內部類===================
外圍類:靜態變量
|---靜態內部類:普通變量
|---靜態內部類:靜態變量
外圍類:靜態方法
|---靜態內部類:靜態方法
|---靜態內部類:普通方法
===↓↓↓局部內部類===================
局部變量(final)
外圍類:普通變量
外圍類:靜態變量
外圍類:普通方法
外圍類:靜態方法
===↓↓↓匿名內部類===================
外圍類:普通變量
外圍類:靜態變量
外圍類:普通方法
外圍類:靜態方法
10086
對比和總結
面試題
面試題:
1、靜態內部類和成員內部類有什么不同?(美團)
2、Anonymous Inner Class (匿名內部類)是否可以繼承其它類,是否可以implements(實現)interface(接口)?
3、補全代碼:
interface Inter {
public void show();
}
class Outer {
public static Inter method() {// 返回值是接口的方法
// 補全代碼↓↓↓
return
// 補全代碼↑↑↑
}
}
public class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}