java中的內部類總結

內部類不是很好理解,但說白了其實也就是一個類中還包含著另外一個類

如同一個人是由大腦、肢體、器官等身體結果組成,而內部類相當于其中的某個器官之一,例如心臟:它也有自己的屬性和行為(血液、跳動)

顯然,此處不能單方面用屬性或者方法表示一個心臟,而需要一個類

而心臟又在人體當中,正如同是內部類在外部內當中

實例1:內部類的基本結構

//外部類
class Out {private int age = 12;//內部類class In {public void print() {System.out.println(age);}}
}public class Demo {public static void main(String[] args) {Out.In in = new Out().new In();in.print();//或者采用下種方式訪問/*Out out = new Out();Out.In in = out.new In();in.print();*/}
}

運行結果:12

從上面的例子不難看出,內部類其實嚴重破壞了良好的代碼結構,但為什么還要使用內部類呢?

因為內部類可以隨意使用外部類的成員變量(包括私有)而不用生成外部類的對象,這也是內部類的唯一優點

如同心臟可以直接訪問身體的血液,而不是通過醫生來抽血

?

程序編譯過后會產生兩個.class文件,分別是Out.class和Out$In.class

其中$代表了上面程序中Out.In中的那個 .

Out.In in = new Out().new In()可以用來生成內部類的對象,這種方法存在兩個小知識點需要注意

  1.開頭的Out是為了標明需要生成的內部類對象在哪個外部類當中

  2.必須先有外部類的對象才能生成內部類的對象,因為內部類的作用就是為了訪問外部類中的成員變

?

實例2:內部類中的變量訪問形式

class Out {private int age = 12;class In {private int age = 13;public void print() {int age = 14;System.out.println("局部變量:" + age);System.out.println("內部類變量:" + this.age);System.out.println("外部類變量:" + Out.this.age);}}
}public class Demo {public static void main(String[] args) {Out.In in = new Out().new In();in.print();}
}

運行結果:

局部變量:14
內部類變量:13
外部類變量:12

從實例1中可以發現,內部類在沒有同名成員變量和局部變量的情況下,內部類會直接訪問外部類的成員變量,而無需指定Out.this.屬性名

否則,內部類中的局部變量會覆蓋外部類的成員變量

而訪問內部類本身的成員變量可用this.屬性名,訪問外部類的成員變量需要使用Out.this.屬性名

?

實例3:靜態內部類

class Out {private static int age = 12;static class In {public void print() {System.out.println(age);}}
}public class Demo {public static void main(String[] args) {Out.In in = new Out.In();in.print();}
}

運行結果:12

可以看到,如果用static 將內部內靜態化,那么內部類就只能訪問外部類的靜態成員變量,具有局限性

其次,因為內部類被靜態化,因此Out.In可以當做一個整體看,可以直接new 出內部類的對象(通過類名訪問static,生不生成外部類對象都沒關系)

?

實例4:私有內部類

class Out {private int age = 12;private class In {public void print() {System.out.println(age);}}public void outPrint() {new In().print();}
}public class Demo {public static void main(String[] args) {//此方法無效/*Out.In in = new Out().new In();in.print();*/Out out = new Out();out.outPrint();}
}

運行結果:12

如果一個內部類只希望被外部類中的方法操作,那么可以使用private聲明內部類

上面的代碼中,我們必須在Out類里面生成In類的對象進行操作,而無法再使用Out.In in = new Out().new In() 生成內部類的對象

也就是說,此時的內部類只有外部類可控制

如同是,我的心臟只能由我的身體控制,其他人無法直接訪問它

?

實例5:方法內部類

class Out {private int age = 12;public void Print(final int x) {class In {public void inPrint() {System.out.println(x);System.out.println(age);}}new In().inPrint();}
}public class Demo {public static void main(String[] args) {Out out = new Out();out.Print(3);}
}

運行結果:

3
12

在上面的代碼中,我們將內部類移到了外部類的方法中,然后在外部類的方法中再生成一個內部類對象去調用內部類方法

如果此時我們需要往外部類的方法中傳入參數,那么外部類的方法形參必須使用final定義

至于final在這里并沒有特殊含義,只是一種表示形式而已

?

6、匿名內部類

?

首先回顧下之前的匿名內部類:  

匿名內部類的格式
  new 接口或者接口名(){
        重寫方法
    };

?本質:是該類或者接口的子類對象

匿名內部類方式使用多線程
1、new Thread(){代碼…}.start();
2、new Thread(new Runnable(){代碼…}).start();

注意://在jdk 1.8以前匿名內部類調用外部類對象的屬性或者方法時外部類需要使用final修飾 如下面代碼所示:

public class Test1 {public void studay(){System.out.println("進入外部類的方法");}//定義一個內部類class Main {public int i = 10;public synchronized void operationSup(){System.out.println("進入內部類的方法");try {i--;System.out.println("Main print i = " + i);Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {//        final SyncException se=new SyncException();final Test1 a=new Test1();//在jdk 1.8以前匿名內部類調用外部類對象的屬性或者方法時外部類需要使用final修飾//定義一個匿名內部類Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {a.studay();}},"t1");t1.start();}
}

當:jdk版本換成1.8以下?final Test1 a=new Test1(); 沒有使用final修飾及 Test1 a=new Test();

此時調用外部類方法a.studay();就會報錯 所以此時一個內部類中用外部類中的對象,該對象必須要final修飾才能通過;

就那這個代碼來說,內部類thread在main方法執行完后不會隨著方法被GC回收,而方法中的a(Test1)對象可以看做是一個局部變量,在方法執行完后就會被回收,

而在內部類中卻還有繼續用這個a對象,所以要用final修飾該對象,使其會在內部類中復制一份副本給內部類使用。當然它的值是不會改變的。

?

轉載于:https://www.cnblogs.com/a8457013/p/8080707.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/251254.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/251254.shtml
英文地址,請注明出處:http://en.pswp.cn/news/251254.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

elementPlus關閉彈窗,頁面原先滾動條消失

一開始以為是彈窗內容超過一屏引起,改為一屏內也不能解決。 打開控制臺,發現彈窗后自動給body標簽加上了類el-popup-parent–hidden,關閉后也沒去除,因此手動刪除該類。 document.getElementsByTagName(body)[0].className ;

在Windows下如何創建虛擬環境(默認情況下)

很多小伙伴平時在使用Python的時候,有的項目需要使用Python2來進行開發,有的項目則是需要Python3來進行開發。當不清楚怎么分開環境的時候,此時兩個環境開始打架,彼此傻傻分不清楚。虛擬環境作為隔離的利器應運而生,其…

javascript --- 隱藏內部實現(最小暴露原則)

看下面的一個例子: function doSomething(a) {b a doSomethingElse( a * 2 );console.log( b * 3 ); }function doSomethingElse(a) {return a - 1; }var b;doSomething( 2 ) ; // 15上述代碼中的doSomethingElse實際上應該是doSomething的"私有"部分,根據最小暴露…

selenium python 入門-元素定位

環境搭建 安裝教程 http://www.testclass.net/selenium_python/install-selenium/ chrome瀏覽器 還需要下載chrome driver 把下載的chromedriver .exe放到chrome安裝目錄下的Application目錄下和 python所在的安裝目錄下,比如我的目錄是C:\Program Files (x86)\Goog…

ES5程序設計轉ES6 筆記

課程鏈接 1. 立即執行函數 特點:執行結束,立即銷毀;獨立作用域執行符號()只能跟在表達式后面,不能放在函數聲明后分號可以寫在前面/后面document為傳入實參,doc為形參 ;(function(doc){...co…

DPDK helloworld 源碼閱讀

在 DPDK Programmers Guides 中的 EAL 一篇中有一個圖可以很清晰地看到一個DPDK的應用程序的大致執行思路: 初始化檢查CPU支持、微架構配置等完成后,執行main()函數。 第一步是 rte_eal_init(),核心初始化和啟動。其中線程使用的是pthread庫&…

javascript --- 作用域和閉包

執行環境: // 定義了變量或函數有權訪問的其他數據,決定了它們各自的行為 // 每個執行環境都有一個變量對象與之對應,執行環境中所定義的所有變量和函數都保存在變量對象中 // 某個執行環境中的所有代碼執行完畢后,該執行環境被銷毀,保存在其中的所有變量和函數定義也隨之銷毀…

異步下載圓形進度條顯示進度

圓形進度條參考鏈接即可:使用css3實現圓形進度條 需求點擊下載后遮罩層顯示下載進度: 1.圓形進度條參考以上鏈接,有點小瑕疵,可更改定位距離實現重合。 2.遮罩層: .lbOverlay{display: none;position: fixed;left: 0;…

javascript基本功

隱式類型轉換 var a {_default: 0,toString: function () {return a._default} } if (a 1 && a 2 && a 3) {console.log(解) } 訪問一個變量的時候進行攔截 var _default 0 Object.defineProperty(window, a, {get() {return _default} }) if (a 1 &am…

深信服筆試,抓兔子

*問題描述:抓兔子n個排成一排的洞,編號為1到n,兔子每天晚上會跳到相鄰的一個洞里,小q每天只能白天檢查其中的一個洞,小q會告訴你每天檢查的洞,分析是否一定能抓到兔子示例:3個洞,第一…

es6 --- 模塊

function foo(){var something cool;var another [1, 2, 3];function doSomething() {console.log( something );}function doAnother() {console.log( another.join( " ! " ) );} } // 是一個不明顯的閉包,doSomething()和doAnother()保持了foo的內部作用域接下來…

Java之遞歸遍歷目錄,修改指定文件的指定內容

EditProperties.java 1 package PropertiesOperation.Edit;2 3 import java.io.File;4 5 /**6 * 替換指定Porpoerties文件中的指定內容7 * 三個參數:8 * filePath:存放properties文件的目錄9 * srcStr:需要替換的字符串 10 * desStr&…

學習日志---7

1.復習Linux hadoop hdfs MapReduce基礎知識 1,列舉linux常用命令 shutdown now reboot mkdir mkdir -p touch filename rm -r filename rm -rf filename vi filename i--->可編輯狀態 esc --> : --->wq 保存退出 q! wq! cat grep find ifconfig ping user…

javascript --- 屬性描述符

從ES5開始,所有的屬性都具備了屬性描述符 var myObject {a: 2 };Object.getOwnPropertyDescriptor(myObject, "a"); //{ // value:2, // writable: true, // 可寫 // enumerable: true, // 可枚舉 // configurble: true // 可配置 //}定義屬性…

看了嗎網址鏈接

sklearn實戰-乳腺癌細胞數據挖掘(博主親自錄制視頻) https://study.163.com/course/introduction.htm?courseId1005269003&utm_campaigncommission&utm_sourcecp-400000000398149&utm_mediumshare # -*- coding: utf-8 -*- ""&qu…

JMeter 性能測試進階實戰

課程簡介 本課程制作的主要目的是為了讓大家快速上手 JMeter,期間穿插了大量主流項目中用到的技術,以及結合當今主流微服務技術提供了測試 Dubbo 接口、Java 工程技術具體實施方案,注重實踐、注意引導測試思維、拒絕枯燥的知識點羅列、善于用…

javascript --- 混入

顯示混入: function mixin(sourceObj, targetObj){for(var key in sourceObj){ // 遍歷source中的所有屬性if(!(key in targetObj)) { // 找到targetz中沒有的屬性targetObj[key] sourceObj[key];}}return targetObj; }var Vehicle {engines: 1,iginition: function() {c…

php源碼代目錄

ext :存放動態和內建模塊的目錄,在這里可以找到所有的php官方虧站,并且也可以在這里編寫擴展; main:包含php的主要宏定義; pear: PHP擴展與應用庫; sapi:包含不同服務器抽象層的代碼; TSRM:Zend和PHP的"線程安全資源管理器"目錄; Z…

bzoj1231 [Usaco2008 Nov]mixup2 混亂的奶牛——狀壓DP

題目&#xff1a;https://www.lydsy.com/JudgeOnline/problem.php?id1231 小型狀壓DP&#xff1b; f[i][j] 表示狀態為 j &#xff0c;最后一個奶牛是 i 的方案數&#xff1b; 所以下一個只能是和它相差大于 k 而且不在狀態中的奶牛。 代碼如下&#xff1a; #include<iostr…

JavaScript高級程序設計閱讀筆記

2020-11-15 通過初始化指定變量類型 數字-1 對象null和null的比較&#xff08;不理解&#xff09;使用局部變量將屬性查找替換為值查找&#xff08;算法復雜度&#xff09;循環的減值迭代&#xff0c;降低了計算終止條件的復雜度switch快多個變量聲明逗號隔開使用數組和對象字面…