類與接口(二)java的四種內部類詳解

引言

內部類,嵌套在另一個類的里面,所以也稱為 嵌套類;

內部類分為以下四種:

  • 靜態內部類
  • 成員內部類
  • 局部內部類
  • 匿名內部類

一、靜態內部類

靜態內部類: 一般也稱”靜態嵌套類“,在類中用static聲明的內部類。

因為是static,所以不依賴于外圍類對象實例而獨立存在,靜態內部類的可以訪問外圍類中的所有靜態成員,包括private的靜態成員。

同時靜態內部類可以說是所有內部類中獨立性最高的內部類,其創建對象、繼承(實現接口)、擴展子類等使用方式與外圍類并沒有多大的區別。

public class OuterClass {//外圍類public int aa; //實例成員private static float f = 1.5f;//private的靜態成員static void println() {System.out.println("這是靜態方法");}protected static class StaticInnerClass{//protected的靜態內部類float a;public StaticInnerClass() {a = f;// 外圍類的private靜態變量println();//外圍類的靜態方法}}
}class OtherClass{public static void main(String[] args) {//創建靜態內部類的對象OuterClass.StaticInnerClass staticInnerClass = new OuterClass.StaticInnerClass(); } 
}

二、成員內部類

成員內部類: 定義在類的內部,而且與成員方法、成員變量同級,即也是外圍類的成員之一,因此 成員內部類 與 外圍類 是緊密關聯的。

注意:
這種緊密關聯指的是,成員內部類的對象的創建必須依賴于外圍類的對象(即沒有外圍類對象,就不可能創建成員內部類)。因此,成員內部類有以下3個特點:

  • 成員內部類可以訪問外圍類的所有成員,包括私有成員;
  • 成員內部類是不可以聲明靜態成員(包括靜態變量、靜態方法、靜態成員類、嵌套接口),但有個例外---可以聲明 static final的變量, 這是因為編譯器對final類型的特殊處理,是直接將值寫入字節碼;
  • 成員內部類對象都隱式地保存了一個引用,指向創建它的外部類對象;或者說,成員內部類的入口是由外圍類的對象保持著(靜態內部類的入口,則直接由外圍類保持著)

成員內部類中的 this,new關鍵字:

  • 獲取外部類對象:OuterClass.this
  • 明確指定使用外部類的成員(當內部類與外部類的名字沖突時):
    OuterClass.this.成員名
  • 創建內部類對象的new:外圍類對象.new
//先創建外圍類對象
OuterClass outer=new OuterClass();
//創建成員內部類對象
OuterClass.InnerClass inner=outer.new InnerClass();

1. 成員內部類的對象創建

??我們知道,成員內部類就像外圍類的實例成員一樣,一定要存在對象才能訪問,即成員內部類必須綁定一個外圍類的對象。上面已經介紹了成員內部類的創建格式了,我們直接看一個例子

public class OuterClass {//外圍類public int aa; //實例成員private static float f = 1.5f;//private的靜態成員public void initInnerClass() {System.out.println("內部類的初始化方法");}public void createInnerClass() {////外圍類的成員方法中創建成員內部類對象InnerClass innerClass = new InnerClass();}class InnerClass{//成員內部類private double aa; //與圍類的變量aa的名字重復public InnerClass(){this.aa = OuterClass.this.aa + f;//明確指定兩個aa的所屬initInnerClass();}}   
}//其他類
class OtherClass{public static void main(String[] args) {//其他類中創建成員內部類OuterClass oc = new OuterClass();//外部類對象//創建內部類對象OuterClass.InnerClass innerClass = oc.new InnerClass();}
}

??注意上面的例子中,在外圍類的成員方法中創建成員內部類 與 在其他類中或靜態方法中創建成員內部的方式是不一樣的。

補充幾點:

  • 成員內部類可以繼續包含成員內部類,而且不管一個內部類被嵌套了多少層,它都能透明地訪問它的所有外部類所有成員;
  • 成員內部可以繼續嵌套多層的成員內部類,但無法嵌套靜態內部類;靜態內部類則都可以繼續嵌套這兩種內部類。

下面的例子是基于上面的例子進行改造:

class InnerClass{//成員內部類private double aa; //與圍類的變量aa的名字重復public InnerClass(){this.aa = OuterClass.this.aa + f;//明確指定兩個aa的所屬initInnerClass();}public  class InnerInnerCalss2{//成員內部類中的成員內部類protected double aa = OuterClass.this.aa;//最外層的外圍類的成員變量}//InnerInnerCalss2}//InnerClass

2. 繼承成員內部類

在內部類的訪問權限允許的情況下,成員內部類也是可以被繼承的。由于成員內部類的對象依賴于外圍類的對象,或者說,成員內部類的構造器入口由外圍類的對象把持著。因此,繼承了成員內部類的子類必須要與一個外圍類對象關聯起來。同時,子類的構造器是必須要調用父類的構造器方法,所以也只能通過父類的外圍類對象來調用父類構造器。

下面的例子也是基于上面的例子的,只貼出多出的部分代碼。

class ChildClass extends OuterClass.InnerClass{//成員內部類的子類的構造器的格式public ChildClass(OuterClass outerClass) {outerClass.super();//通過外圍類的對象調用父類的構造方法}
}

三、局部內部類

局部內部類: 就是在方法、構造器、初始化塊中聲明的類,在結構上類似于一個局部變量。因此局部內部類是不能使用訪問修飾符。

局部內部類的兩個訪問限制:

  • 對于局部變量,局部內部類只能訪問final的局部變量。不過,后期JDK(忘了是JDK幾了)局部變量可不用final修飾,也可以被局部內部類訪問,但你必須時刻記住此局部變量已經是final了,不能再改變。
  • 對于類的全局成員,局部內部類定義在實例環境中(構造器、對象成員方法、實例初始化塊),則可以訪問外圍類的所有成員;但如果內部類定義在靜態環境中(靜態初始化塊、靜態方法),則只能訪問外圍類的靜態成員。
public class OuterClass {private int a = 21;static {//靜態域中的局部內部類class LocalClass1{//  int z = a; //錯誤,在靜態的作用域中無法訪問對象成員}}{//實例初始化塊中的局部內部類class localClass2{          }}public OuterClass(){int x = 2;final int y = 3;// x = 3;//若放開此行注釋,編譯無法通過,因為局部變量x已經是final類型//構造器中的局部內部類class localClass3{int z = y; //可以訪問final的局部變量int b = a;//可以訪問類的所有成員//訪問沒有用final修飾的局部變量int c = x;}}public void createRunnable() {final int x = 4;//方法中的局部內部類class LocalClass4 implements Runnable {//@Overridepublic void run() {System.out.println("局部final變量:"+x);System.out.println("對象成員變量:"+a);}}}
}

四、匿名內部類

匿名內部類: 與局部內部類很相似,只不過匿名內部類是一個沒有給定名字的內部類,在創建這個匿名內部類后,便會立即用來創建并返回此內部類的一個對象引用。

作用:匿名內部類用于隱式繼承某個類(重寫里面的方法或實現抽象方法)或者實現某個接口。

匿名內部類的訪問限制: 與局部內部類一樣,請參考局部內部類;

匿名內部類的優缺點:
優點: 編碼方便快捷;
缺點:

  • 只能繼承一個類或實現一個接口,不能再繼承其他類或其他接口。
  • 只能用于創建一次對象實例;

下面的例子是我們創建線程時經常用到的匿名內部類的方式來快速地創建一個對象的例子:

 class MyOuterClass {private int x = 5;void createThread() {final int a = 10;int b = 189;// 匿名內部類繼承Thread類,并重寫Run方法Thread thread = new Thread("thread-1") {int c = x;  //訪問成員變量int d = a;  //final的局部變量int e = b; //訪問沒有用final修飾的局部變量@Overridepublic void run() {System.out.println("這是線程thread-1");}};// 匿名內部類實現Runnable接口Runnable r = new Runnable() {@Overridepublic void run() {System.out.println("線程運行中");}};}
}

總結

類 型訪問修飾符聲明靜態成員綁定外圍類
靜態內部類四種訪問修飾符可以聲明不綁定
成員內部類四種訪問修飾符final static 的變量外,其余靜態成員都不行綁定
局部內部類不可以聲明不可以聲明取決于此內部類的聲明環境
匿名內部類不可以聲明不可以聲明取決于此內部類的聲明環境


轉載于:https://www.cnblogs.com/jinggod/p/8503143.html

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

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

相關文章

單例設計模式和多線程

單例設計模式 單例&#xff1a;整個項目中&#xff0c;有某個類或者某些特殊的類&#xff0c;屬于該類的對象只能建立一個。 #include<iostream> using namespace std;class MyCAS { private:MyCAS(){}private:static MyCAS *m_instance;public:static MyCAS *GetInstanc…

運行imgui例程

背景&#xff1a;目前在做一個視覺測試系統&#xff0c;需要做一個界面&#xff0c;將相機獲取的圖像&#xff0c;以及測試過程中的數據呈現在界面上&#xff0c;在我印象里&#xff0c;做界面就用qt吧&#xff0c;直到這個月真要開始做界面了&#xff0c;我的領導給我建議用im…

性能測試總結(三)--工具選型篇

性能測試總結(三)--工具選型篇 本篇文章主要簡單總結下性能測試工具的原理以及如何選型。性能測試和功能測試不同&#xff0c;性能測試的執行是基本功能的重復和并發&#xff0c;需要模擬多用戶&#xff0c;在性能測試執行時需要監控指標參數&#xff0c;同時性能測試的結果不是…

創建一個最簡單的imgui測試用例

在上一篇文章中&#xff0c;我們初步認識了一下imgui,并且成功運行了他提供的demo。這只是開始學習imgui的第一步&#xff0c;在實際使用時&#xff0c;我們需要將imgui應用到自己的工程中去&#xff0c;所以你需要具備將imgui加到你工程中去的能力&#xff0c;簡單起見&#x…

idea中maven的setting.xml的配置

2019獨角獸企業重金招聘Python工程師標準>>> <?xml version"1.0" encoding"UTF-8"?> <settings xmlns"http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance&qu…

ref和out區別總結

ref&#xff1a;是必需要先初始化才能用,但調用時可以對它什么也不做.out&#xff1a;可以不初始化也能用,但調用時一定要對其賦值(即使已經初始化的也要賦值,哪怕是賦一個和原來一樣的值).轉載于:https://www.cnblogs.com/gjnsmallworld/p/7216206.html

繼 承(面向對象特征之一)

1&#xff1a;成員變量。 當子父類中出現一樣的屬性時&#xff0c;子類類型的對象&#xff0c;調用該屬性&#xff0c;值是子類的屬性值。 如果想要調用父類中的屬性值&#xff0c;需要使用一個關鍵字&#xff1a;super This&#xff1a;代表是本類類型的對象引用。 Super&…

如何將cv::Mat類型轉換為imgui中的ImTextureID類型

背景&#xff1a; 我原來的工程是使用opencv的&#xff0c;所以程序中的圖像都是表示為cv::Mat類型&#xff0c;為了能夠在imgui窗口中顯示我的cv::Mat的圖像&#xff0c;我找到了下面這個函數&#xff1a; void ImGui::Image(ImTextureID user_texture_id, const ImVec2&…

react native 原生模塊橋接的簡單說明

原文出自&#xff1a;https://github.com/prscX/awes...博客鏈接&#xff1a;https://ssshooter.com/2019-02... Android 創建原生模塊包 通過繼承 ReactPackage 為你的原生模塊包創建 Java 類&#xff0c;可以這么寫&#xff1a;覆蓋 createNativeModules 和 createViewManage…

UVa 1354 天平難題 枚舉二叉樹

題意&#xff1a;給出房間寬度 r 和 s 個掛墜的重量 wi&#xff0c;設計一個盡量寬的天平&#xff0c;掛著所有掛墜。天平由一些長度為 1 的木棍組成&#xff0c;木棍的每一端要么掛一個掛墜&#xff0c;要么掛另外一個木棍。 這題卡了很久&#xff0c;看了很多大神的代碼&…

通過指針便利圖像元素

for (size_t y 0; y < image.rows; y) {//row_ptr為第y行的頭指針&#xff0c;unsigned char* row_ptr image.ptr<unsigned char>(y);for (size_t x 0; x < image.cols; x) {//data_ptr: 指向待訪問像素unsigned char* data_ptr &row_ptr[x*image.channels…

[精華][推薦]SSO CAS單點登錄框架學習 搭建詳細步驟及源碼

1.了解單點登錄 SSO 主要特點是: SSO 應用之間使用 Web 協議(如 HTTPS) &#xff0c;并且只有一個登錄入口. SSO 的體系中有下面三種角色: 1) User(多個) 2) Web 應用(多個) 3) SSO 認證中心(一個) 2.SSO 實現包含以下三個原則 1) 所有的登錄都在 SSO 認證中心進行。 2) SS…

電腦下載的M4A格式文件怎么轉換為MP3格式

M4A文件格式并不是一個家喻戶曉的名字&#xff0c;與&#xff2d;&#xff30;&#xff13;格式相比&#xff0c;知名度遠遠落后。但是&#xff0c;這并不意味著它無關緊要&#xff0c;有時候我們下載的音樂可能就是M4A格式的&#xff0c;如果換一個設備播放可能就會出現格式不…

python-for循環

一、功能 for 循環提供了python中最強大的循環結構&#xff08;for循環是一種迭代循環機制&#xff0c;而while循環是條件循環&#xff0c;迭代即重復相同的邏輯操作&#xff0c;每次操作都是基于上一次的結果&#xff0c;而進行的&#xff09; Python for循環可以遍歷任何序列…

六、利用frp穿透連接內網的linx系統和windows系統

服務端的配置 # frps.ini [common] bind_port 7000 說明&#xff1a;防火墻放行該端口 啟動&#xff1a;./frps -c ./frps.ini 后臺啟動&#xff1a;nohup ./frps -c ./frps.ini & 客戶端的配置 (1)windows系統 # frpc.ini [common] server_addr x.x.x.x server_port 70…

根據相機內參進行圖像去畸變

cv::Mat img; cv::Mat img_undistort; double fx,fy, cx, cy, k1, k2, p1, p2, k3;for(int v 0; v < img.rows; v){for(int u 0; u < img.cols; u){//根據內參數&#xff0c;計算歸一化坐標系下的坐標點double x (u-cx)/fx;double y (v-cy)/fy;double r2 x*x y*y;/…

initialize方法與load方法比較

load方法和initialize方法類似點 1. 都只會調用一次2. 父類在子類之前加載 復制代碼不同點在于&#xff1a; 1. 加載時間不同&#xff0c;load方法在main()函數前進行調用&#xff0c;initialize在第一次調用類的所屬方法時在調用<可能永遠不調用>。2. load方法不會被Cat…

KindEditor

1、進入官網 2、下載 官網下載&#xff1a;http://kindeditor.net/down.php 3、文件夾說明 ├── asp asp示例 ├── asp.net asp.net示例 ├── attached 空文件夾&#xff0c;放置關聯文件attached ├── …

service mysqld start,Failed to start mysqld.service: Access denied

service mysqld start 然后報&#xff1a; AUTHENTICATING FOR org.freedesktop.systemd1.manage-units Authentication is required to start mysqld.service.Authenticating as: lll,,, (lll)Password: polkit-agent-helper-1: pam_authenticate failed: Authentication fa…

使用realsense t265測試svo2.0視覺里程計

畢業三年了&#xff0c;現在是第二份工作&#xff0c;第一份工作已經結束一年半了&#xff0c;這意味著&#xff0c;我有一年半的時間沒有搞視覺SLAM相關的東西了&#xff0c;雖然在第二份工作也是做視覺相關的&#xff0c;但是只是用到一些目標識別和跟蹤的知識&#xff0c;并…