Python:多執行緒及多程序的使用-Threading and multiprocessing
義在另一個給類裡面或者方法裡面,這樣的類就被稱為內部類。
內部類可以分為四種:成員內部類、區域性內部類、匿名內部類、靜態內部類,下面我們逐一介紹這四種內部類。
成員內部類
他定義在另一個類中。一般定義格式如下
class C{
class D{
}
}
因為類C相對與類D在外面,我們且稱類C為外部類。
成員內部類可以無條件訪問外部類的屬性和方法,但是外部類想要訪問內部類屬性或方法時,必須要建立一個內部類物件,然後通過該物件訪問內部類的屬性或方法
成員內部類無條件訪問外部類的屬性和方法
class C{
private String name = "外部類";
public void run(){
System.out.println("外部類奔跑");
}
class D{
public void say(){
System.out.println(name);
run();
}
}
}
外部類訪問內部類屬性和方法
class C{
private String name = "外部類";
public void run(){
System.out.println("外部類奔跑");
}
/*使用內部類的屬性和方法*/
public void eat(){
D d = new D();
System.out.println(d.value);
d.say();
}
class D{
private String value = "DDD";
public void say(){
System.out.println(name);
run();
}
}
}
外部類屬性或方法隱藏
如果成員內部類的屬性或者方法與外部類的同名,將導致外部類的這些屬性與方法在內部類被隱藏,也可按照該格式呼叫,外部類.this.屬性/方法。
class C{
private String name = "外部類";
public void run(){
System.out.println("外部類奔跑");
}
/*使用內部類的屬性和方法*/
public void eat(){
D d = new D();
System.out.println(d.value);
d.say();
}
class D{
private String value = "DDD";
private String name = "內部類";
public void say(){
System.out.println(C.this.name);
System.out.println(name);
run();
}
}
}
建立內部類物件
顯然成員內部類是寄生於外部類,建立內部類物件就必須先創造外部類物件。之後建立內部類有兩種方式。
public class Test10 {
public static void main(String[] args) {
/*方式1建立成員內部類物件*/
C c = new C();
C.D d = c.new D();
/*方式2建立成員內部類物件*/
C.D d1 = c.getClassD();
}
}
class C{
private String name = "外部類";
public void run(){
System.out.println("外部類奔跑");
}
/*建立一個返回D物件的方法*/
public D getClassD(){
return new D();
}
/*使用內部類的屬性和方法*/
public void eat(){
D d = new D();
System.out.println(d.value);
d.say();
}
class D{
private String value = "DDD";
private String name = "內部類";
public void say(){
System.out.println(C.this.name);
System.out.println(name);
run();
}
}
}
成員內部類的訪問許可權
成員內部類前可加上四種訪問修飾符。
private:僅外部類可訪問。
protected:同包下或繼承類可訪問。
default:同包下可訪問。
public:所有類可訪問。
區域性內部類
區域性內部類存在於方法中。
他和成員內部類的區別在於區域性內部類的訪問許可權僅限於方法或作用域內。
class K{
public void say(){
class J{
}
}
}
注意事項:區域性內部類就像區域性變數一樣,前面不能訪問修飾符以及static修飾符。
匿名內部類
下面我們先通過一段程式碼初步瞭解一下匿名內部類。
public class Test13 {
public static void main(String[] args) {
driveCar(new Car(){
@Override
public void drive() {
System.out.println("駕駛著BMW汽車");
}
});
}
public static void driveCar(Car car){
car.drive();
}
}
interface Car {
void drive();
}
分析以上程式碼知道靜態方法driveCar需要一個Car物件,我們通過實現介面建立一個匿名類物件傳遞過去。事實上還可以通過繼承類來建立一個匿名內部類物件。
注意事項:匿名內部類沒有構造方法。也是唯一沒有構造方法的內部類。匿名內部類和區域性內部類只能訪問外部類的final變數。
靜態內部類
靜態內部類和成員內部類相比多了一個static修飾符。它與類的靜態成員變數一般,是不依賴於外部類的。同時靜態內部類也有它的特殊性。因為外部類載入時只會載入靜態域,所以靜態內部類不能使用外部類的非靜態變數與方法。
同時可以知道成員內部類裡面是不能含靜態屬性或方法的。
class U {
static class I {
}
}
內部類的好處
- 完善了Java多繼承機制,由於每一個內部類都可以獨立的繼承介面或類,所以無論外部類是否繼承或實現了某個類或介面,對於內部類沒有影響。
- 方便寫事件驅動程式。
總結
public class Test15 {
public static void main(String[] args) {
//初始化bean1
Test15.Bean1 bean1 = new Test15().new Bean1();
bean1.i++;
//初始化bean2
Test15.Bean2 bean2 = new Test15.Bean2();
bean2.j++;
//初始化3
Bean bean = new Bean();
Bean.Bean3 bean3 = bean.new Bean3();
bean3.k++;
}
class Bean1 {
public int i = 0;
}
static class Bean2 {
public int j = 0;
}
}
class Bean {
class Bean3 {
public int k = 0;
}
}
靜態內部類物件的建立一般是外部類.內部類 類名 = new 外部類.內部類();
成員內部類物件的建立一般是外部類.內部類 類名 = 外部類物件名.new 內部類();