Java基礎教程——內部類


內部類

內部類(inner class)是定義在另一個類中的類
內部類的好處:
|--1.隱藏機制:內部類封裝性更好,隱藏在一個類之中,同一包中的其他類也不能訪問
|--2.內部類可以訪問外圍類的私有數據

成員內部類

member inner class

成員內部類.png

可以訪問外部類的所有成員變量和方法(無論靜態、非靜態)
自身沒有靜態成員
|--外部類里面創建成員內部類的實例: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();
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM