1. 程式人生 > >Java學習系列(二十三)Java面向物件之內部類詳解

Java學習系列(二十三)Java面向物件之內部類詳解

一、前言

內部類也稱寄生類,就是把一個類放在類裡面(即內部類的上一級程式單元是類)定義,將其作為外部類的成員。內部類主要用幾種定義形式:靜態(static)內部類,非靜態內部類,匿名內部類(也就是沒有名字的寄生類)。內部類的好處就是內部類可以直接外部類的(包括私有)成員,反之不能。下面我們通過一些例項來詳細講解一下Java中內部類的使用及幾種定義形式的相互呼叫。

二、例項說明

(1)匿名內部類:當程式建立匿名內部類時,會立即建立匿名內部類(實現類)的例項。

interface IBreathe {
	void breathe();
}

/**
 * 匿名內部類的使用,定義形式如下:
 * 
 * new 介面() | 父類構造器<引數>){ 
 * 		// 類體部分... 
 * };
 * 
 * @author [*昨日重現*] 
[email protected]
* @since version 1.0 * @datetime 2015年4月29日 下午10:17:40 */ public class Anonymous { // 這裡相當於建立了介面IBreathe的匿名實現類,並建立了匿名內部類的例項 // 將實現類的例項賦值給介面變數 ,屬於向上轉型 IBreathe breathe = new IBreathe() { // 必須實現接口裡的所有抽象方法 @Override public void breathe() { System.out.println("呼吸新鮮空氣..."); } }; public static void main(String[] args) { Anonymous anonymous = new Anonymous(); anonymous.breathe.breathe(); } }

注意以下幾點:
1)只要父類是抽象類或者是一個介面,那麼其子類中的方法都可以使用匿名內部類來實現;反過來也就是說使用匿名內部類有個前提:它必須顯示地繼承一個父類或實現一個介面。
2)匿名內部類必須實現介面或抽象類中所有的抽象方法。
3)匿名內部類適合建立只需一次使用的類。
4)匿名內部類不能有構造器而且程式以後無法再訪問它,因為它沒有類名。

(2)靜態內部類:它屬於外部類(宿主類)的靜態成員,所以它不能訪問外部類的非靜態成員(屬性、方法)。

/**
 * 外部類(宿主類)中包含靜態內部類作為外部類的一個靜態成員
 * 
 * @author [*昨日重現*] [email protected]
* @since version 1.0 * @datetime 2015年4月29日 下午11:00:51 */ public class Out { private static String name = "張三"; private String sex = "男"; static class In { private static String name = "李四"; public void info() { // 靜態內部類不能訪問外部類的非靜態成員,所以下面這句會編譯不通過 // System.out.println("外部類的sex = " + sex); System.out.println("in的info方法被呼叫,name:" + name); } } public static void main(String[] args) { // 列印結果(編譯器遵循就近原則):in的info方法被呼叫,name:李四 // 這裡只需要把外部類當成靜態內部類的包就行了 // 所以In前加不加Out.都是一樣的 new In().info(); new Out.In().info(); } }

如果要在外部類的外面訪問靜態內部類的成員:Out.In in = new Out.In(); in.info();當然,靜態內部類也可以派生子類:class InSub extends Out.In {},編寫和呼叫方式與普通類一樣,這裡不再贅述。下面看看重點來看看非靜態內部類定義和使用。

(3)非靜態內部類:在建立非靜態內部類的例項前,必須先建立外部類例項,也就是說非靜態內部類必須寄生在外部類的例項(Outer.this)裡面。所以在建立非靜態內部類的例項前,必須先建立外部類例項。 

/**
 * 非靜態內部類的使用
 * 
 * @author [*昨日重現*] [email protected]
 * @since version 1.0
 * @datetime 2015年4月29日 下午11:26:06
 */

public class Outer {
	int number = 10;

	// 定義非靜態內部類
	class Inner {
		int number = 100;

		public void info() {
			int number = 1000;
			System.out.println("Inner內部類的info()方法被呼叫~");
			System.out.println("number變數的值為:" + number);// 方法的區域性變數,所以為1000
			System.out.println("number變數的值為:" + this.number);// 指向寄生類成員,所以為100
			System.out.println("number變數的值為:" + Outer.this.number);// 指向宿主類成員,所以為10
		}
	}

	/**
	 * 通過外部類的方法來訪問寄生類的成員(屬性、方法)
	 */
	public void info() {
		System.out.println("Outer外部類的info()方法被呼叫~");
		Inner inner = new Inner();
		inner.info();
		System.out.println(inner.number);
	}

	public static void main(String[] args) {
		new Outer().info();
	}
}
如果在外部類的外面使用內部類,那麼在建立非靜態內部類的例項前,必須先建立外部類例項。 
Outer outer = new Outer();
Outer.Inner in = outer.new Inner();
等價於==》Outer.Inner in2 = new Outer().new Inner();

當然非靜態內部類也可以派生子類,如下:

//非靜態內部類派生子類
class InnerSub extends Outer.Inner {
	public InnerSub() {
		// 由於Outer.Inner是非靜態內部類,因此必須使用"宿主物件"來呼叫它的構造器
		new Outer().super();
	}}

三、總結

1)有static修飾的內部類屬於外部類本身,沒有static修飾的內部類屬於類例項 。

2)記住方法是誰的,就用誰來呼叫。

3)沒有static修飾的內部類,【必須寄生在“外部類”的例項裡】;反之則寄生在外部類本身裡。

4)靜態內部類是寄生在類本身裡面的,所以就不需要程式設計師理會宿主。-把外部類當成靜態內部類的包就行了。

5)非靜態內部類派生子類:由於子類的構造器必須呼叫父類構造器一次,因此必須在子類構造器中使用宿主物件來呼叫它的構造器。

四、結束語

關於Java中的內部類的定義和使用基本內容就這些,後面會陸續更新包括:正則表示式、Java效能優化、學習JVM等等,敬請關注。

相關推薦

Java學習系列(十三)Java面向物件之內部類

一、前言 內部類也稱寄生類,就是把一個類放在類裡面(即內部類的上一級程式單元是類)定義,將其作為外部類的成員。內部類主要用幾種定義形式:靜態(static)內部類,非靜態內部類,匿名內部類(也就是沒有名字的寄生類)。內部類的好處就是內部類可以直接外部類的(包括私有)

Java學習系列(十一)Java面向物件之註解

一、前言 Java中的註解Annotation運用到很多方面,比如之前講的單元測試中的@Test、Spring、SpringMVC還有其他框架等等。Java本身自帶的註解也有一些,比如:@Override(子類要重寫/覆寫父類的對應方法)、@Deprecated(表

Java學習系列()Java面向物件之列舉

一、前言  今天我們來講講列舉,希望通過這篇部落格大家能對列舉有個更全面的瞭解。列舉是一種例項(大寫)數固定的類(不能再建立例項),列舉改變了常量的宣告方式,而且它在編譯期間就限定了型別。列舉多用於確定的狀態數(如:滑鼠上下左右、IM訊息已讀未讀)、型別數(如:系統

Java基礎學習筆記十三 Java核心語法之反射

負責 目錄 boolean tostring 筆記 str 編譯 三種 進制 類加載器 類的加載 當程序要使用某個類時,如果該類還未被加載到內存中,則系統會通過加載,鏈接,初始化三步來實現對這個類進行初始化。 加載就是指將class文件讀入內存,並為之創建一個Clas

Java 學習筆記 維陣列和物件陣列

定義二維陣列 int[][] a = new int[4][5]; 可以不指定列數 int[][] a = new int[4][]; 獲取行 int i = a.length(); 如果使用第一個例子,這裡就是返回4 獲取列 int i = a[0].length();使用第一個例子,這裡就是

Java學習筆記第四天——面向物件

面向物件的思想: 面向物件是基於面向過程的程式設計思想 面向過程:強調的是每一個功能的步驟 面向物件:強調的是物件,然後由物件去呼叫功能 面向物件的思想特點: A:是一種更符合我們思考習慣的思想 B:可以將複雜的事情簡單化 C:將我們從執行者變成了

Java學習之第三章——面向物件程式設計

學習面向物件(OOP)內容的三條主線 1.java類及類的成員 2.面向物件的三大特徵(封裝 Encapsulation,繼承 Inheritance,多型 Polymorphism) 3.其他關鍵字 OOP:Object Oriented Programming

JavaSE入門學習14:Java面向物件之內部類

       一內部類概述        內部類(Inner Class)就是定義在另外一個類裡面的類。與之對應,包含內部類的類被稱為外部類。        內部類的主要作用如下:        A內

Java學習筆記(1)面向物件

1、Java面向物件中類與物件的概念和使用 方法的定義: 方法就是一段可以重複呼叫的程式碼。 定義格式: 訪問修飾符 返回值型別 方法名(){ 方法主體 } 方法的返回值型別: void型別不需要返回值,其

Java學習系列(十四)Java正則表示式

前言 正則表示式可以說是用來處理字串的一把利器,它是一個專門匹配n個字串的字串模板,本質是查詢和替換。在例項演示之前先了解一下Pattern、Matcher這兩個工具類,Pattern:編譯好的帶匹配的模板(如:Pattern.compile("[a-z]{2}")

Java學習系列()Java註釋、識別符號、基本資料型別及其轉換易錯點

Java註釋 前面我們講了下Java的執行機制及JDK的安裝配置等相關操作,今天我們先從Java的註釋開始。Java註釋對程式本身沒有影響,主要是開發者提供一些輔助資訊來更好的理解。首先,Java的註釋分三種:單行、多行以及文件註釋。單行://後面的內容就是單行註釋;多行:

Java學習筆記(5):3.面向物件之方法

  方法是類或物件的行為特徵的抽象,方法是類或物件最重要的組成成分。但從功能上看,方法完全類似於傳統結構化程式設計裡的函式。值得指出的是,Java裡的方法不能獨立存在,所有的方法必須定義在類裡。方法在邏輯上要麼屬於類,要麼屬於物件。 1.方法的所屬性   永遠不要把方法當成

JAVA面向物件之內部類

內部類 在一個類的內部宣告的類,稱為內部類(也叫內嵌類)。內部類只能在包含它的類中使用,同時它可以看作是該包含類的一段特殊程式碼,可以直接使用該包含類的變數和方法。 內部類編譯後也會形成一個單獨的class,但它附屬於其包含類。建立內部類的物件時會有一個對外

C++學習) C++面向物件程式設計方法概述

(1)面向過程與面向物件的比較 面向過程程式設計方法(C語言) 分析出要解決所需要的步驟,然後用函式把各步驟逐個實現,執行時依次呼叫各個函式即可。 程式 = 演算法 + 資料結構 面向物件程式設計方法(C++語言) 把問題分解成各個物件,描述各個物件的

Java面向物件之異常

目錄 Java面向物件之異常【一】 Java面向物件之異常【二】 捕獲異常的規則 訪問異常資訊 異常對方法重寫的影響 finally詳解

Hadoop學習之路(十三)MapReduce中的shuffle

就是 多個 流程 http cer 分開 分享圖片 數據分區 bsp 概述 1、MapReduce 中,mapper 階段處理的數據如何傳遞給 reducer 階段,是 MapReduce 框架中 最關鍵的一個流程,這個流程就叫 Shuffle 2、Shuffle: 數

FineBI學習系列之FineBI新建儀表板(圖文

功能 過程 平臺 tps RM 獲取數據 esc 表格 學習     不多說,直接上幹貨!   這是來自FineBI官網提供的幫助文檔 http://help.finebi.com/ 目錄: 1、描述 2、新建

osgEarth的Rex引擎原理分析(十三)PagerLoader的traverse過程

目標:(十七)中問題48 主要包含兩個過程: 1、以處理過請求的載入 這是真正意義上的載入,剛創建出來的請求是從快取或檔案沒有關聯影像、高程等資料的,需要經過多執行緒處理後才有資料(詳見(十七))。對於這些處理過的請求,在PagerLoader的更新遍歷traverse中會進行實質性的處

面向物件七大原則

單一職責原則    定義:一個類只負責一個領域的相應職責。 開閉原則 定義:軟體實體應對擴充套件開放,而對修改關閉。 里氏替換原則   定義:所有引用基類的物件能夠透明的使用其子類的物件。 依賴倒轉原則   定義:抽象

【深度學習系列】卷積神經網路CNN原理(一)——基本原理

轉自:https://www.cnblogs.com/charlotte77/p/7759802.html 上篇文章我們給出了用paddlepaddle來做手寫數字識別的示例,並對網路結構進行到了調整,提高了識別的精度。有的同學表示不是很理解原理,為什麼傳統的機