成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java編程中的內部類

開發 后端
本文節選自《JAVA編程思想》中關于Java內部類的段落。內部類是在其他類內定義的類。雖然看上去象某種代碼隱藏機制,但可以實現更多功能。

內部類:在其它類內定義的類,不同于組合。雖然看上去象某種代碼隱藏機制,但可以實現更多功能 -了解包含它的類并可與之交換數據,而且內部類的代碼可以更優雅、清晰。

內部類定義:包含在其它類內。使用與非內部類沒有太大區別。

典型用法:outer class通過方法返回inner class的引用。

區別之一:內部類名嵌套在外部類(outer class)內,在Out class的non-static方法之外用OuterClassName.InnerClassName的形式定義內部類對象。

注意,非static內部類只能在Out class的non-static方法中生成對象;在其它類中,也必須使用Out class的外部類對象實例。這就保證了下面所說的鏈接問題。

區別之二:內部類可以為private和protected。

Inner Class只是一種名稱隱藏(name-hiding)和組織代碼方式?NO。

內部類對象有一個到創建它的外部類對象的鏈接(link to the enclosing object that made it),因而可以直接的、沒有任何限制地訪問該外部類對象的成員,而且內部類可以訪問outer class的所有成員(包括private)(C++的嵌套類沒有這個特性);而outer class訪問inner class的成員,必須創建Inner class的對象,可以訪問任何成員(包括private)。

內部類對象中隱式包含了一個外部類對象的引用。內部類對象構建需要outer class對象的引用,如果沒有,編譯報錯(非靜態inner class)。

.this和.new:前者用來返回Outer class引用,編譯期可知道和檢查正確類型,無運行時開銷;后者用來由outer class對象創建其內部類的對象,OutClassObject.new InnerClassName ()(注意,不能用outClassObj.new OutClassName.InnerClassName())。

嵌套類(nested class):static inner class,其對象創建不需要outer class對象引用,也可在static方法中創建。

內部類與upcasting

類實現了接口(interface),其它方法就可以用該interface作為參數,而不一定必須用該類(包括類對象定義)(類似繼承)。可以利用upcasting->interface。

upcasting內部類->基類或者接口(尤其是后者),使內部類有了用武之地。實現接口內部類可以完全不可見、不可用(通過private或protected),所獲得的只是基類或接口的引用(通過private,無法進行downcasting,protected,同一個包內,或者繼承類可以進行downcasting),方便隱藏實現細節。

接口成員自動為public

private內部類可以阻止任何依賴于類型的代碼,進行所有實現細節的隱藏。而且,擴展接口也沒有任何意義,因為無法訪問pubic接口之外的方法,這可以使JAVA產生更有效率的代碼 。

inner class可以在任意作用域內定義(如方法內)。

兩個理由:1. 實現一個接口

2. 需要一個不公開的類輔助解決復雜的問題

inner class形式

1. 方法內的內部類; 2. 方法中的一個作用域內的內部類; 3. 實現接口的匿名內部類; 4. 繼承的匿名內部類(基類含有參的構造器); 4. 進行成員初始化的匿名內部類; 5. 使用實例初始化塊進行構造的匿名內部類(匿名類沒有構造器)。

局部內部類(local inner class) :在方法內或方法的一個作用域中定義的內部類。局部內部類在域外不可見并不代表其對象也不可用。條件域內定義的內部類不代表它是條件創建的。

匿名內部類(anonymous inner class) :new T(){...}; {...}為匿名內部類的定義,";"不可少(;只是該語句的結束,而不是用來表示匿名內部類的結束,所以沒有什么特殊的地方),創建一個繼承自T的匿名類的對象,得到的引用可自動upcast to T。是前面定義內部類的一種簡寫,只是該類沒有名稱。

前面是基類構造器為默認構造器的情況,當基類構造器有參數時:new T(args){...};此時會調用基類相應構造器。

匿名內部類初始化 :當需要用到外部定義類的對象時,傳遞的引用參數必須為final,否則編譯報錯;匿名類不能有命名的構造器(當然不能,類本身就沒有名字),可以通過實例初始化(instance initialization)來完成構造器的功能。由于實例初始化不能重載(不代表只能有一個Instance initialization clause),所以匿名內部類只能有一個構造器。

匿名內部類只能在繼承類和實現接口中2選一,且只能實現一個接口。

prefer classes to interfaces. (寧愿選擇類,而不是接口?)

嵌套類(nested class):static inner class。有點類似C++嵌套類的概念,但Java的嵌套類可以訪問outer class的所有成員(包括private,當然只能通過外部類對象訪問non-static成員)。

1. 不需要通過outer class對象來創建嵌套類對象(.new不可用?);

2. 不能通過嵌套類對象訪問non-static outer class對象(意思是像非嵌套類那樣直接訪問);

3. 嵌套類對象中不包含outer class對象引用(.this不可用)。

4. 非嵌套內部類不能有static成員、方法和嵌套類(fields、methods級別必須與class本身一致,non-static不能含有static,non-static、static內可以含有non-static)。

嵌套類可以位于接口內部,不違反接口的規則(不能定義接口實例?),只代表把嵌套類位于接口的命名空間下,位于接口內部的類自動為public static(public嵌套類),而且嵌套類本身就可以實現該接口,好處在于可以在嵌套類內編寫該接口所有實現中都要用到的代碼。

嵌套類的另一個用途:編寫測試代碼。 為每個類編寫main函數增加代碼長度,可以把main放在嵌套類內,要測試該類運行該嵌套類即可;而在發布的時候只要在打包前簡單的刪除該嵌套類的.class文件即可。

多重嵌套的類(non-static和static)可以沒有限制的訪問任何外層類的所有對象。

為什么用內部類?

不是總是直接和接口打交道,有時候需要用的是接口的實現。(可以實現多個接口,但不能繼承多個類)

理由:每個內部類可以獨立繼承自一個實現,不受outer class是否已經繼承另一實現的限制。從效果上來說,inner class提供了多繼承(multiple-inheritance,繼承自多個類)的能力,提供了另一種實現多個接口的方法(相比多繼承,這個似乎沒那么重要,因為多繼承只能通過內部類來實現)。

額外特性:

1. 內部類可以有多個實例,每個實例可以擁有獨立于outer class對象的不同信息;

2. 一個outer class可以有多個內部類,每個內部類可以以不同的方式實現同一個接口或者繼承同一個類(參見習題22,兩個內部類不同方式實現同一個接口,只有內部類才能完成這些);

3. 內部類實例創建時間并不受到外部類對象創建的限制;

4. 用內部類不會制造"is-a"關系的混亂,每個內部類都是個實體。

閉包(closure)和回調(callback)

閉包是一種可調用的對象,它記錄了來自創建它的作用域的一些信息。

內部類是一種面向對象的閉包,不僅包含了外部類的信息,而且通過包含一個指向外部類對象的引用,可以操作所有成員,包括private。

回調,通過其它對象攜帶的信息,可以在稍后的某個時刻調用初始對象。

Java不支持指針類型,不能通過指針來實現回調。但內部類提供的閉包是種比較好的解決方案,更靈活,更安全(參見例callbacks)。

  1. private class Closure implements Incrementable {   
  2.     public void increment() {   
  3.     // Specify outer-class method, otherwise   
  4.     // you’d get an infinite recursion:   
  5.         Callee2.this.increment();   
  6.     }   
  7. }    

回調的價值在于靈活性,可以在運行時決定需要調用的方法。 GUI編程將體現得更明顯。

內部類與控制框架(control frameworks)

一個應用程序框架(application framework)是指一個用來解決一個特定類型問題的類或類的集合。典型的應用方法是,繼承其中一個或多個類,重寫某些方法。重寫方法的代碼將通用解決方案特殊化,來解決特定問題。例如模板函數模式。 設計模式將不變的和變化的事情分開。

控制框架是用來響應事件的一類特殊的應用程序框架 。主要用來響應事件的系統稱為事件驅動系統(event-driven system),如GUI。

內部類使得控制框架的創建和使用變得簡單 。控制框架本身不包括要控制的事物的特定信息。這些信息在繼承過程中,由算法的action()部分實現時提供。控制框架中變化的事情是各種事件對象的不同action,這通過創建不同event繼承類來實現。(例event)

控制事件用abstract類代替接口?

內部類在控制框架中兩個作用:

1. 用來表示解決問題所需的各種不同的action()。

2. 內部類可以直接訪問外部類的所有成員,因而使得實現變得更靈活。

參見greenhouse(溫室)的例子。

內部類的繼承

內部類指向outer class object的引用必須初始化,而在它的繼承類中并不存在要聯接的缺省對象,必須使用特殊的語法明確指出這種關聯。

繼承自內部類的類構造器不能是默認構造器,要有個outer class的引用作為參數,而且必須加上enclosingClassReference.super();語句,編譯才能通過。

內部類能override?繼承outer class,像重寫方法一樣重寫內部類并不起作用,此時兩個內部類只是兩個獨立的實體。可以顯式指定內部類的繼承關系,然后通過復寫base inner class的方法,來實現多態。 參見例BigEgg2.

  1. //: innerclasses/BigEgg2.java   
  2. // Proper inheritance of an inner class.   
  3. import static net.mindview.util.Print.*;   
  4. class Egg2 {   
  5.     protected class Yolk {   
  6.       public Yolk() { print("Egg2.Yolk()"); }   
  7.       public void f() { print("Egg2.Yolk.f()");}   
  8. }   
  9.     private Yolk y = new Yolk();   
  10.     public Egg2() { print("New Egg2()"); }   
  11.     public void insertYolk(Yolk yy) { y = yy; }   
  12.     public void g() { y.f(); }   
  13. }   
  14. public class BigEgg2 extends Egg2 {   
  15.     public class Yolk extends Egg2.Yolk {   
  16.         public Yolk() { print("BigEgg2.Yolk()"); }   
  17.         public void f() { print("BigEgg2.Yolk.f()"); }   
  18. }   
  19.     public BigEgg2() { insertYolk(new Yolk()); }   
  20.     public static void main(String[] args) {   
  21.         Egg2 e2 = new BigEgg2();   
  22.         e2.g();   
  23. }   
  24. /* Output:   
  25. Egg2.Yolk()   
  26. New Egg2()   
  27. Egg2.Yolk()   
  28. BigEgg2.Yolk()   
  29. BigEgg2.Yolk.f()   
  30. *///:~  
  31.  

局部內部類

局部內部類(local inner class)不能有訪問限定符;有訪問局部final變量和outer class所有類的權限;可以有命名的構造器;在方法外不能訪問。

絕大部分情況下,可以用匿名類來替代局部內部類,除非:

1. 需要命名的構造器,或者需要重載構造器

2. 需要多個內部類的對象

此時就要用Local Inner class。

【編輯推薦】

  1. Java的局部內部類以及final類型的參數和變量
  2. 沒有原生數據類型,Java會更好嗎?
  3. 20個開發人員非常有用的Java功能代碼
  4. 走進Java 7中的模塊系統
  5. 2009年十大Java技術解決方案
責任編輯:yangsai 來源: 《JAVA編程思想》
相關推薦

2020-01-15 11:14:21

Java算法排序

2011-07-21 15:44:33

Java內部類

2020-12-14 10:23:23

Java內部類外部類

2011-03-29 14:11:15

內部類

2010-02-05 15:32:33

Java內部類

2023-10-19 13:24:00

Java工具

2023-03-06 07:53:36

JavaN種內部類

2015-12-08 09:05:41

Java內部類

2009-07-29 09:18:49

Java內部類

2019-12-23 14:32:38

Java內部類代碼

2010-08-26 10:41:45

C#內部類

2012-04-17 11:21:50

Java

2020-09-21 07:00:42

Java內部類接口

2009-08-26 18:00:07

C#內部類

2020-01-12 19:10:30

Java程序員數據

2009-06-11 11:07:25

Java局部內部類Final類型

2020-10-29 08:31:15

Java同步回調編程語言

2011-11-23 10:59:18

Javafinal

2011-03-15 10:41:05

內部類

2009-07-22 16:13:40

iBATIS用法SqlMapTempl
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 97人澡人人添人人爽欧美 | 久久av一区二区三区 | 欧美综合久久 | 全免费a级毛片免费看视频免 | 福利视频一区二区 | 欧美亚洲视频 | 美女爽到呻吟久久久久 | 99热首页 | 精品国产乱码久久久久久牛牛 | 免费精品视频 | 青青草视频免费观看 | 99精品国产一区二区三区 | 国产一区二区激情视频 | 中文字幕在线观看成人 | 亚洲综合二区 | 日韩欧美在 | 九九久久久久久 | 久久大全| 久久伊人影院 | 日本黄色的视频 | 狠狠色狠狠色综合系列 | 亚洲欧美中文日韩在线v日本 | 亚洲国产18 | 亚洲精品国产第一综合99久久 | 国产在线视频一区 | 亚洲色图综合网 | 国产91丝袜 | 国产做a爱片久久毛片 | 先锋av资源在线 | 成人在线视频免费观看 | 蜜月va乱码一区二区三区 | 伦理午夜电影免费观看 | 亚洲精品中文字幕av | 久久精品16 | 日韩欧美三级电影在线观看 | 精品欧美一区二区精品久久 | 成年人在线播放 | 999久久久久久久久 国产欧美在线观看 | 久久中文字幕在线 | 东京久久 | 久久网一区二区 |