Java學習系列(二十三)Java面向對象之內部類詳解
來源:程序員人生 發布時間:2015-06-09 08:26:56 閱讀次數:3126次
1、前言
內部類也稱寄生類,就是把1個類放在類里面(即內部類的上1級程序單元是類)定義,將其作為外部類的成員。內部類主要用幾種定義情勢:靜態(static)內部類,非靜態內部類,匿名內部類(也就是沒著名字的寄生類)。內部類的好處就是內部類可以直接外部類的(包括私有)成員,反之不能。下面我們通過1些實例來詳細講授1下Java中內部類的使用及幾種定義情勢的相互調用。
2、實例說明
(1)匿名內部類:當程序創建匿名內部類時,會立即創建匿名內部類(實現類)的實例。
interface IBreathe {
void breathe();
}
/**
* 匿名內部類的使用,定義情勢以下:
*
* new 接口() | 父類構造器<參數>){
* // 類體部份...
* };
*
* @author [*昨日重現*] lhy_ycu@163.com
* @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)只要父類是抽象類或是1個接口,那末其子類中的方法都可使用匿名內部類來實現;反過來也就是說使用匿名內部類有個條件:它必須顯示地繼承1個父類或實現1個接口。
2)匿名內部類必須實現接口或抽象類中所有的抽象方法。
3)匿名內部類合適創建只需1次使用的類。
4)匿名內部類不能有構造器而且程序以后沒法再訪問它,由于它沒有類名。
(2)靜態內部類:它屬于外部類(宿主類)的靜態成員,所以它不能訪問外部類的非靜態成員(屬性、方法)。
/**
* 外部類(宿主類)中包括靜態內部類作為外部類的1個靜態成員
*
* @author [*昨日重現*] lhy_ycu@163.com
* @since version 1.0
* @datetime 2015年4月29日 下午11:00:51
*/
public class Out {
private static String name = "張3";
private String sex = "男";
static class In {
private static String name = "李4";
public void info() {
// 靜態內部類不能訪問外部類的非靜態成員,所以下面這句會編譯不通過
// System.out.println("外部類的sex = " + sex);
System.out.println("in的info方法被調用,name:" + name);
}
}
public static void main(String[] args) {
// 打印結果(編譯器遵守就近原則):in的info方法被調用,name:李4
// 這里只需要把外部類當做靜態內部類的包就好了
// 所以In前加不加Out.都是1樣的
new In().info();
new Out.In().info();
}
}
如果要在外部類的外面訪問靜態內部類的成員:Out.In in = new Out.In(); in.info();固然,靜態內部類也能夠派生子類:class InSub extends Out.In {},編寫和調用方式與普通類1樣,這里不再贅述。下面看看重點來看看非靜態內部類定義和使用。
(3)非靜態內部類:在創建非靜態內部類的實例前,必須先創建外部類實例,也就是說非靜態內部類必須寄生在外部類的實例(Outer.this)里面。所以在創建非靜態內部類的實例前,必須先創建外部類實例。
/**
* 非靜態內部類的使用
*
* @author [*昨日重現*] lhy_ycu@163.com
* @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();
}}
3、總結
1)有static修飾的內部類屬于外部類本身,沒有static修飾的內部類屬于類實例 。
2)記住方法是誰的,就用誰來調用。
3)沒有static修飾的內部類,【必須寄生在“外部類”的實例里】;反之則寄生在外部類本身里。
4)靜態內部類是寄生在類本身里面的,所以就不需要程序員理睬宿主。-把外部類當做靜態內部類的包就好了。
5)非靜態內部類派生子類:由于子類的構造器必須調用父類構造器1次,因此必須在子類構造器中使用宿主對象來調用它的構造器。
4、結束語
關于Java中的內部類的定義和使用基本內容就這些,后面會陸續更新包括:正則表達式、Java性能優化、學習JVM等等,敬請關注。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈