Java學習個人備忘錄之內部類
阿新 • • 發佈:2018-12-26
內部類: 將一個類定義在另一個類的裡面,對裡面那個類就稱為內部類.
class Outer { private int num = 3; class Inner //它想訪問Outer中的num, 如果在外面就需要建立一個物件,然後通過公開的介面訪問,但是現在Outer內部, 就可以直接訪問了.這樣方便 { void show() { System.out.println("show run..." + num); } } //如果現在想訪問Inner就需要這樣 public void method() { Inner in = new Inner(); in.show(); } //內部類由於在內部, 相當於定義在了成員的位置上, 所以可以用成員修飾符, 如: //private class Test{} static class Inner { static void function() { System.out.println("function run......"+num); } } }
內部類訪問特點:
1. 內部類可以直接訪問外部類中的成員.
2. 外部類要訪問內部類, 必須建立內部類的物件.
一般用於類的設計。
分析事物時, 發現該事物描述中還有事物,而且這個事物還在訪問被描述事物的內容。
這時就把還有的事物定義成內部類來描述。
class InnerClassDemo { public static void main(String[] args) { Outer out = new Outer(); out.method(); //直接訪問外部類中的內部類中的成員. Outer.Inner in = new Oouter().new Inner(); in.show(); //如果內部類是靜態, 那就相當於一個外部類了. Outer.Inner in = new Outer.Inner(); in.show(); //如果內部類是靜態的,成員是靜態的. Outer.Inner.function(); //如果內部類中定義了靜態成員,該內部類也必須是靜態的. } }
細節
class Outer { int num = 3; class Inner { int num = 4; void show() { int num = 5; System.out.println(num);//5 System.out.println(this.num);//4 System.out.println(Outer.this.num);//3 } } void method() { new Inner().show(); } } class InnerClassDemo2 { public static void main(String[] args) { new Outer().method(); } }
為什麼內部類能直接訪問外部類中成員呢?
那是因為內部類持有了外部類的引用-----外部類名.this
內部類可以存放在區域性位置上
class Outer
{
int num = 3;
Object method()
{
final int x = 9;
class Inner
{
void show()
{
System.out.println("show..."+num);
}
}
Object in = new Inner();
return in;//0x0045
}
}
class InnerClassDemo3
{
public static void main(String[] args)
{
Outer out = new Outer();
Object obj = out.method();//0x0045
}
}
內部類在區域性位置上只能訪問區域性中被final修飾的區域性變數。
匿名內部類, 就是內部類的簡寫格式.
必須有前提:
內部類必須繼承或者實現一個外部類或者介面.
匿名內部類: 其實就是一個匿名子類物件.
格式: new 父類or介面(){子類內容}
abstract class Demo
{
abstract void show();
}
class Outer
{
int num = 4;
class Inner extends Demo //這是正常情況
{
void show()
{
System.out.println("show...."+num);
}
}
public void method()
{
new Demo()//這個就叫匿名內部類
{
void show()
{
System.out.println("show...."+num);
}
}
}
}
匿名內部類的應用
interface Inter
{
void show1();
void show2();
}
class Outer
{
public void method()
{
new Inter()
{
public void show1()
{}
public void show2()
{}
}.show1(); //呼叫了show1的方法, 相當於 new Inner().show1();
//或者用下面的方法
Inter in = new Inter()
{
public void show1()
{}
public void show2()
{}
}
in.show1();
in.show2();
}
}
通常的使用場景之一:
當函式引數是介面型別時,而且介面中的方法不超過三個.
可以用匿名內部類作為實際引數進行傳遞.
class InnerClassDemo5
{
public static void main(String[] args)
{
show(new InterImpl());
}
public static void show(Inter in)
{
in.show1();
in.show2();
}
}
class InterImpl implements Inter
{
}
物件的初始化過程
class Fu
{
int num = 9;
{
System.out.println("Fu");
}
Fu()
{
super();
//顯示初始化
//構造程式碼塊初始化
show();
}
void show()
{
System.out.println("fu show..."+num); //被覆蓋,執行子類
}
}
class Zi extends Fu
{
int num = 8;
{
System.out.println("Zi");
}
Zi()
{
super();
//顯示初始化
//構造程式碼塊初始化
show();
}
void show()
{
System.out.println("zi show..."+num);
}
}
class Inner
{
public static void main(String[] args)
{
new Zi();
}
}
/*
Fu
zi show...0
Zi
zi show...8
*/