內部類別是指在一個外部類別的內部再定義一個類別。類別名稱不需要和資料夾相同。
內部類別分為: 成員內部類別、局部內部類別、靜態巢狀類別、匿名內部類別 。
1.成員內部類
成員內部類是最普通的內部類,它的定義為位於另一個類的內部,形如下面的形式:
class Outter { private int age = 12; class Inner { private int age = 13; public void print() { int age = 14; System.out.println("局部变量:" + age); System.out.println("内部类变量:" + this.age); System.out.println("外部类变量:" + Outter.this.age); } } } public class test1 { public static void main(String[] args) { Outter out = new Outter(); Outter.Inner in = out.new Inner(); in.print(); } }
運行結果:
局部变量:14 内部类变量:13 外部类变量:12
reee看出:成員內部類,就是作為外部類別的成員,可以直接使用外部類別的所有成員和方法,即使是private的。雖然成員內部類別可以無條件地存取外部類別的成員,而外部類別想存取成員內部類別的成員卻不是這麼隨心所欲了。在外部類別中如果要存取成員內部類別的成員,必須先建立一個成員內部類別的對象,再透過指向這個物件的參考來存取:
class Outter { private int age = 12; public Outter(int age) { this.age = age; getInInstance().print(); //必须先创建成员内部类的对象,再进行访问! } private Inner getInInstance() { return new Inner(); } class Inner { public void print() { System.out.println("内部类没同名,所以直接调用外部类成员变量:" + age); } } } public class test1 { public static void main(String[] args) { Outter out = new Outter(10); } }
運作結果:
内部类没同名,所以直接调用外部类成员变量:10
內部類別可以擁有private存取權限、protected存取權限、public存取權限及包存取權限。
例如上面的例子,如果成員內部類Inner用private修飾,則只能在外部類的內部訪問,如果用public修飾,則任何地方都能訪問;如果用protected修飾,則只能在同一個包下或繼承外部類別的情況下存取;如果是預設存取權限,則只能在同一個套件下存取。
這一點和外部類別有一點不一樣,外部類別只能被public和套件存取兩種權限修飾。
我個人是這麼理解的,由於成員內部類別看起來像是外部類別的一個成員,所以可以像類別的成員一樣擁有多種權限修飾。要注意的是,成員內部類別不能含有static的變數和方法。因為成員內部類別需要先創建了外部類,才能創建它自己的
2.局部內部類
局部內部類是定義在一個方法或者一個作用域裡面的類,它和成員內部類的區別在於內部類別的存取僅限於方法內或該作用域內。
定義在方法裡的內部類別:
class Outter { private int age = 12; public void Print(final int x) { //这里局部变量x必须设置为final类型! class Inner { public void inPrint() { System.out.println(x); System.out.println(age); } } new Inner().inPrint(); } } public class test1 { public static void main(String[] args) { Outter out = new Outter(); out.Print(10); } }
運行結果:
10 12
本例中我們將內部類別移到了外部類別的方法中,然後在外部類別的方法中再產生一個內部類別物件去呼叫內部類別方法。如果此時我們需要往外部類別的方法中傳入參數,那麼外部類別的方法形參必須使用final定義。
換句話說,在方法中定義的內部類別只能存取方法中final類型的局部變量,這是因為在方法中定義的局部變數相當於一個常數,它的生命週期超出方法運行的生命週期,由於局部變數被設定為final,所以不能再內部類別中改變局部變數的值。 (這裡看到網路上有不同的解釋,還沒有徹底搞清楚==)
定義在作用域內的內部類別:
class Outter { private int age = 12; public void Print(final boolean x) { //这里局部变量x必须设置为final类型! if(x){ class Inner { public void inPrint() { System.out.println(age); } } new Inner().inPrint(); } } } public class test1 { public static void main(String[] args) { Outter out = new Outter(); out.Print(true); } }
3.靜態巢狀類
又叫靜態局部類、巢狀內部類,就是修飾為static的內部類別。聲明為static的內部類,不需要內部類別物件和外部類別物件之間的聯繫,就是說我們可以直接引用outer.inner,也就是不需要建立外部類別,也不需要建立內部類別。
class Outter { private static int age = 12; static class Inner { public void print() { System.out.println(age); } } } public class test1 { public static void main(String[] args) { Outter.Inner in = new Outter.Inner(); in.print(); } }
可以看到,如果用static 將內部內靜態化,那麼內部類別就只能存取外部類別的靜態成員變量,具有限制。
其次,因為內部類別被靜態化,因此Outter.Inner可以當做一個整體看,可以直接new 出內部類別的物件(透過類別名稱存取static,生不產生外部類別物件都沒關係)
4.匿名內部類別
匿名內部類別應該是平時我們編寫程式碼時用得最多的,在編寫事件監聽的程式碼時使用匿名內部類別不但方便,而且使程式碼更加容易維護。下面這段程式碼是一段Android事件監聽程式碼:
scan_bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } }); history_bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } });
这段代码为两个按钮设置监听器,这里面就使用了匿名内部类。具体位置是这段:
new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } }
代码中需要给按钮设置监听器对象,使用匿名内部类能够在实现父类或者接口中的方法情况下同时产生一个相应的对象,但是前提是这个父类或者接口必须先存在才能这样使用。当然像下面这种写法也是可以的,跟上面使用匿名内部类达到效果相同:
private void setListener() { scan_bt.setOnClickListener(new Listener1()); history_bt.setOnClickListener(new Listener2()); } class Listener1 implements View.OnClickListener{ @Override public void onClick(View v) { // TODO Auto-generated method stub } } class Listener2 implements View.OnClickListener{ @Override public void onClick(View v) { // TODO Auto-generated method stub } }
这种写法虽然能达到一样的效果,但是既冗长又难以维护,所以一般使用匿名内部类的方法来编写事件监听代码。同样的,匿名内部类也是不能有访问修饰符和static修饰符的。
匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于结构化数据处理开源库SPL的相关问题,下面就一起来看一下java下理想的结构化数据处理类库,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于PriorityQueue优先级队列的相关知识,Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java锁的相关问题,包括了独占锁、悲观锁、乐观锁、共享锁等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于枚举的相关问题,包括了枚举的基本操作、集合类对枚举的支持等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于平衡二叉树(AVL树)的相关知识,AVL树本质上是带了平衡功能的二叉查找树,下面一起来看一下,希望对大家有帮助。

封装是一种信息隐藏技术,是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法;封装可以被认为是一个保护屏障,防止指定类的代码和数据被外部类定义的代码随机访问。封装可以通过关键字private,protected和public实现。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

Dreamweaver Mac版
視覺化網頁開發工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具