內部類使用及注意事項
什麼叫內部類呢?
簡單來說將一個類定義到另一個類裡面,裡面那個類就稱為是內部類
內部類的訪問特點:
內部類可以直接訪問外部類中的成員,包括私有成員。外部類要訪問內部類中的成員必須要建立內部類的物件才能訪問。
內部類的用處:
內部類一般用於類的設計。分析事物時,發現該事物描述中還有事物,而且這個事物還在訪問被描述事物的內容。這個時候,這個事物中的事物就定義成內部類來描述。
內部類的修飾符:
由於內部類被定義在成員位置,所以內部類可以被成員修飾符修飾。
內部類可以在其他類中直接訪問,例:
class Outer{
private int num=3;
class Inner{
void show(){
System.out.println("show run"+num);
}
}
public void method(){
Inner in = new Inner();
in.show();
}
}
class InnerDemo{
public static void main(String[]args){
//直接訪問外部類中的內部類中的成員。
Outer.Inner in =new Outer().new Inner();
in.show();
}
}
如果內部類是靜態的,其實相當於一個外部類。可以直接用外部類的物件呼叫內部類類名使用,例:
class Outer{
private static int num=3;
static class Inner{
void show(){
System.out.println("show run"+num);
}
}
public static void method(){
Inner in = new Inner();
in.show();
}
}
class InnerDemo{
public static void main(String[]args){
Outer.Inner in =new Outer.Inner();
in.show();
}
}
如果內部類中定義了靜態的成員,該內部類也必須定義成靜態的否則會編譯失敗,例:
class Outer{
private static int num=3;
class Inner{
void show(){
System.out.println("show run"+num);
}
public static void function(){
System.out.println("function 運行了");
}
}
public static void method(){
Inner in = new Inner();
in.show();
}
}
class InnerDemo{
public static void main(String[]args){
Outer.Inner.function();
}
}
結果為:
Compiling InnerDemo.java……
InnerDemo.java:63: 錯誤: 內部類Outer.Inner中的靜態宣告非法
public static void function(){
^
修飾符 ‘static’ 僅允許在常量變數宣告中使用
InnerDemo.java:68: 錯誤: 無法從靜態上下文中引用非靜態 變數 this
Inner in = new Inner();
^
2 個錯誤
[Finished in 0.6s]
為什麼內部類可以直接訪問外部類的成員:
因為內部類被定義在外部類的成員位置,該內部類就持有了外部類的引用(外部類名.this)
內部類可以放在區域性位置上 ,例:
public class InnerDemo2{
public static void main(String[]args){
new Outer().method();
}
}
class Outer{
int num=3;
void method(){
class Inner{
void show(){
System.out.println("show......"+num);
}
}
Inner in = new Inner();
in.show();
}
}
當內部類處於區域性位置時,該內部類只能訪問區域性中被final修飾的區域性變數。
public class InnerDemo2{
public static void main(String[]args){
Outer out = new Outer();
Object obj = out.method();
}
}
class Outer{
final int num=3;
Object method(){
int x = 9;
class Inner{
void show(){
System.out.println("show......"+x);
}
}
Object in = new Inner();
// in.show();
return in;
}
}
匿名內部類:
匿名內部類其實就是內部類的簡寫格式,是一個匿名 的子類物件,可以直接在類的結束部分加點呼叫。
簡寫的前提:內部類必須實現或者繼承一個外部類或者介面
public class InnerDemo3{
public static void main(String []args){
new Outer().method();
}
}
abstract class Demo{
abstract void show();
}
class Outer{
int num=4;
public void method(){
new Demo(){
void show(){
System.out.println("show......"+num);
}
}.show();
}
}
匿名內部類的使用場景:
當函式引數是介面型別時,且介面中的方法不超過三個,這個時候就可以用匿名內部類作為實際引數進行傳遞。
使用匿名內部類的注意事項:
當在建立內部類物件的時候可以呼叫子類特有的方法,當建立物件的父類引用型別時,就不能引用子類特有的方法了,因為物件已經向上進行了轉型。
例:1.在建立時呼叫
public class InnerDemo5{
public static void main(String[]args){
new Outer().method();
}
}
class Outer{
void method(){
new Object(){
public void show(){
System.out.println("show run");
}
}.show();
}
}
結果如下:
Compiling InnerDemo5.java……
——Output——
show run
[Finished in 0.6s]
2.建立子類物件的父類引用型別時,呼叫子類特有的方法
public class InnerDemo5{
public static void main(String[]args){
new Outer().method();
}
}
class Outer{
void method(){
Object obj = new Object(){
public void show(){
System.out.println("show run");
}
};
obj.show();
}
}
執行結果如下:
Compiling InnerDemo5.java……
InnerDemo5.java:14: 錯誤: 找不到符號
obj.show();
^
符號: 方法 show()
位置: 型別為Object的變數 obj
1 個錯誤
——Output——
[Finished in 0.6s]