Java中的內(nèi)部類你了解嗎
成員內(nèi)部類
1.定義
成員內(nèi)部類是直接定義在類中,不加任何修飾符的(特指不加static修飾的)的內(nèi)部類,可以類比著成員變量來理解,如下面這個代碼段中的Inn類就是一個成員內(nèi)部類
public class Inner1 {
private String o = "外部類屬性";
public class Inn{
private String i = "成員內(nèi)部類屬性";
}
}2.成員內(nèi)部類的使用規(guī)則
- 內(nèi)部類可以直接的訪問外部類的成員變量,但是因為內(nèi)部類也是一個類,所以外部類必須通過內(nèi)部類的對象才能訪問內(nèi)部類的成員變量
- 內(nèi)部類就相當于外部類的成員變量,故而內(nèi)部類與外部類之間可以方便的相互訪問,包括privte權(quán)限修飾的屬性和方法
- 成員內(nèi)部類可以實現(xiàn)“曲線救國”,通過多個內(nèi)部類繼承別的類,變相的實現(xiàn)多繼承
//成員內(nèi)部類
public class Inner1 {
// 外部類的私有屬性o
private String o = "外部類屬性";
public class Inn{
// 內(nèi)部類的私有屬性i
private String i = "成員內(nèi)部類屬性";
private void Itest(){
// 內(nèi)部類直接訪問外部類的屬性,包括私有屬性
System.out.println(o);
}
}
public void Otest(){
// 外部類則要先創(chuàng)建內(nèi)部類的對象再訪問其成員變量,這里注意,也可以訪問其私有屬性
Inn in = new Inn();
in.Itest();
System.out.println(in.i);
}
public static void main(String[] args) {
Inner1 i1 = new Inner1();
i1.Otest();
}
}3.成員內(nèi)部類對象的創(chuàng)建:
- 外部類的內(nèi)部創(chuàng)建:與正常類的對象創(chuàng)建方法一樣,
- 內(nèi)部類名稱 對象名 = new 類名()
public class Inner1 {
private String str1 = "外部類";
// 外部類內(nèi)部創(chuàng)建內(nèi)部類對象
Inn i1 = new Inn();
private class Inn{
private String str2 = "內(nèi)部類";
}
}- 外部類的外部創(chuàng)建:成員內(nèi)部類就相當于是外部類的一個特殊的成員變量,故而,我們知道,成員內(nèi)部類依賴于外部類的存在而存在,也就是說,必須先有外部類的對象才能創(chuàng)建成員內(nèi)部類的對象
- 外部類名稱.內(nèi)部類名稱 對象名 = new 外部類名稱().new 內(nèi)部類名稱()
- 當前,在外部類的外部創(chuàng)建內(nèi)部類對象時,前提也需得內(nèi)部類對外部類的外部是可見的
如下圖, 內(nèi)部類為private,在外部類的外部無法創(chuàng)建該對象

修改內(nèi)部類訪問權(quán)限為public時正確創(chuàng)建 :
public class Inner1 {
private String str1 = "外部類";
// 外部類內(nèi)部創(chuàng)建內(nèi)部類對象
Inn i1 = new Inn();
public class Inn{
private String str2 = "內(nèi)部類";
}
}
class Test{
// 外部類的外部創(chuàng)建外部類的內(nèi)部類對象
Inner1.Inn i2 = new Inner1().new Inn();
}4.內(nèi)部類與靜態(tài)域
- 成員內(nèi)部類可以訪問外部類的靜態(tài)域,但是自己不能定義靜態(tài)變量(成員內(nèi)部類是依賴于外部類的,如果它自己能定義靜態(tài)變量,沒有外部對象也能訪問了,失去其意義)
- 外部類中的靜態(tài)方法也不能使用成員內(nèi)部類(相當于在靜態(tài)變量中調(diào)用成員變量,是不可行的)。
- 為此,特別注意,main方法就是static方法,故而不能直接在外部類的main方法中創(chuàng)建內(nèi)部類對象,要借助外部類才能創(chuàng)建
public class Inner1 {
private String str1 = "外部類";
// 外部類內(nèi)部創(chuàng)建內(nèi)部類對象
Inn i1 = new Inn();
public class Inn{
private String str2 = "內(nèi)部類";
}
public static void main(String[] args) {
// main中創(chuàng)建
Inner1.Inn inn = new Inner1().new Inn();
System.out.println(inn.str2);
}
}靜態(tài)內(nèi)部類:
1.定義:
- 靜態(tài)內(nèi)部類也是定義在類中,但是與成員內(nèi)部類不同的是,它用static修飾,是靜態(tài)內(nèi)部類,可類比靜態(tài)變量進行理解
- static修飾,所以它無需依賴外部類對象,我們可以把它看作一個普通類
public class Inner2 {
private String str1 = new String("外部");
// 靜態(tài)內(nèi)部類
public static class Inn{
private String str2 = new String("靜態(tài)內(nèi)部");
}
}2.靜態(tài)內(nèi)部類的使用規(guī)則:
靜態(tài)內(nèi)部類不能直接訪問外部類的普通成員變量 (普通成員變量有對象才能訪問,所以static不能訪問普通的成員變量),當然,可以通過new一個外部類的對象來達到訪問外部類成員變量的目的
public class Inner2 {
private String str1 = new String("外部");
private static String str3 = new String("外部靜態(tài)屬性");
// 靜態(tài)內(nèi)部類
public static class Inn {
private String str2 = new String("靜態(tài)內(nèi)部");
public void fun(){
// 靜態(tài)內(nèi)部類不能直接訪問外部類的普通成員變量
System.out.println(str1);
// 但可以通過new一個外部類對象訪問
Inner2 i2 = new Inner2();
System.out.println(i2.str1);
// static家族互通
System.out.println(str3);
}
}
}但是,靜態(tài)內(nèi)部類雖然不能直接訪問外部類的成員變量,但是是可以擁有自己的普通成員變量 的
3.靜態(tài)內(nèi)部類對象的創(chuàng)建
- 外部類內(nèi)部:和普通類的用法相同 ,且不同于成員內(nèi)部類,在靜態(tài)內(nèi)部類這里,外部類的靜態(tài)方法中是可以創(chuàng)建靜態(tài)內(nèi)部類的對象(static家族互訪),當然,沒有對象都可以,那么,外部類的成員方法中也是可以創(chuàng)建靜態(tài)內(nèi)部類對象的
- 內(nèi)部類名稱 對象名 = new 類名()
public class Inner2 {
private String str1 = new String("外部");
// 靜態(tài)內(nèi)部類
public static class Inn{
private String str2 = new String("靜態(tài)內(nèi)部");
}
// 直接在類的內(nèi)部創(chuàng)建靜態(tài)內(nèi)部類的對象
Inn i = new Inn();
public static void main(String[] args) {
// 外部類的靜態(tài)方法中創(chuàng)建使用靜態(tài)內(nèi)部類的對象
Inn inn = new Inn();
}
}外部類的外部:
外部類名稱.內(nèi)部類名稱 對象名 = new 外部類名稱. 內(nèi)部類名稱()
public class Inner2 {
private String str1 = new String("外部");
// 靜態(tài)內(nèi)部類
public static class Inn {
private String str2 = new String("靜態(tài)內(nèi)部");
}
}
class Test{
// 外部類的外部創(chuàng)建靜態(tài)內(nèi)部類的對象
Inner2.Inn i = new Inner2.Inn();
}成員內(nèi)部類 VS 靜態(tài)內(nèi)部類
- 成員內(nèi)部類可以訪問外部類的成員域和靜態(tài)域,但是不能擁有自己的靜態(tài)域
- 靜態(tài)內(nèi)部類不可以直接訪問外部類的成員域,但可以擁有自己的成員域,另外,static家族互訪,隨意
方法內(nèi)部類:
1.定義:
直接定義在方法內(nèi)部,不允許使用任何修飾符修飾(包括訪問權(quán)限修飾符,static等),對外部完全隱藏,出了這個方法,這個類就沒有了,可以類比局部變量進行理解
2.方法內(nèi)部類的使用規(guī)則:
除了無法定義static域外,和成員內(nèi)部類基本一樣,這里不再贅述
3.注意形參的使用
方法內(nèi)部類中若使用了方法的形參, 該形參為隱式的final聲明(JDK8之前,必須手動顯式定義為final ,但JDK8以后,直接隱式一定為final)
如下面這個例子:
public class Inner3 {
public void fun(int num){
// 方法內(nèi)部類
class Inn{
public void test(){
// 將下面這行代碼注釋掉,num正??勺鬟\算
// System.out.println(num);
}
}
num ++;
System.out.println(num);
}
public static void main(String[] args) {
Inner3 i3 = new Inner3();
i3.fun(3);
}
}但如果我們的方法內(nèi)部類使用了方法的形參,編譯報錯


匿名內(nèi)部類(函數(shù)式編程)
- 是方法內(nèi)部類的特殊版本,直接不寫類名稱
- 遵從方法內(nèi)部類的所有要求
- 默認會繼承一個類或?qū)崿F(xiàn)一個接口,繼承類一般是繼承抽象類
- 通常是在傳參的過程中使用該類,可以簡化寫法
如之前我們寫的接口傳參:
public class Inner4 {
public static void fun(MessageImpl m) {
m.printMessage();
}
public static void main(String[] args) {
MessageImpl l = new MessageImpl();
fun(l);
}
}
interface IMessage {
void printMessage();
}
class MessageImpl implements IMessage {
public void printMessage() {
System.out.println("aaa");
}
}使用匿名內(nèi)部類可以這樣寫:
public class Inner4 {
public static void fun(IMessage m ){
m.printMessage();
}
public static void main(String[] args) {
// 匿名內(nèi)部類
fun(new IMessage() {
@Override
public void printMessage() {
System.out.println("aaa");
}
});
}
}
interface IMessage {
void printMessage();
}最后,重點掌握成員內(nèi)部類與靜態(tài)內(nèi)部類,以及二者使用區(qū)別。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
springboot如何將http轉(zhuǎn)https
這篇文章主要介紹了springboot如何將http轉(zhuǎn)https,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04
解決mybatis-plus通用mapper調(diào)用報錯:Invalid bound statement
這篇文章主要介紹了解決mybatis-plus通用mapper調(diào)用報錯:Invalid bound statement的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
JAVA 開發(fā)之用靜態(tài)方法返回類名的實例詳解
這篇文章主要介紹了JAVA 開發(fā)之用靜態(tài)方法返回類名的實例詳解的相關(guān)資料,這里主要說明使用異常來得到類名,希望能幫助到大家,需要的朋友可以參考下2017-08-08

