內部類瞭解麼?簡單介紹下[中高]
阿新 • • 發佈:2018-11-19
一定義:
放在一個類的內部類我們就叫內部類。
二作用
1.內部類可以很好的實現隱藏
一般的非內部類,是不允許有 private 與 protected 許可權的,但內部類可以
2.內部類擁有外部類的所有元素的訪問許可權
3. 可以實現多重繼承(重點說下這個)
三 分類
1.靜態內部類:作為類的靜態成員,存在於某個類的內部。 (java.util.Collections,ConcurrentHashMap)
2.成員內部類:作為類的成員,存在於某個類的內部。
3.區域性內部類:存在於某個方法的內部。
4.匿名內部類:存在於某個類的內部,但是無類名的類。
參考程式碼: inner、Outter
/** * 靜態內部類雖然是外部類的成員,但是在未建立外部類的物件的情況下,可以直接建立靜態內部類的物件。 * 靜態內部類可以引用外部類的靜態成員變數和靜態方法,但不能引用外部類的普通成員。 */ public class Outter { static String staticVar = "staitc var靜態變數"; String instinceVar = "普通成員變數"; static { System.out.println("靜態程式碼塊執行:" + staticVar); System.out.println("==========================="); } static void test() { System.out.println("外部類的靜態方法執行"); } static class Inner { static { // 內部類的靜態程式碼塊在外部類初始化的時候,不會被初始化 System.out.println("靜態內部類的靜態程式碼塊"); } public void test2() { System.out.println("staticVar的值為:" + staticVar);// 直接引用外部類的靜態成員變數 test();// 直接引用外部類的靜態方法 // System.out.println(instinceVar); // 試圖引用外部類的非靜態成員變數,不能通過編譯 System.out.println("靜態內部類的方法執行"); } } public static void main(String[] args) { new Outter(); Inner in = new Inner();// 靜態內部類的物件可以直接建立,無需先建立外部類的物件 in.test2(); } }
/** * 成員內部類可以呼叫外部類的所有成員,但只有在建立了外部類的物件後,才能呼叫外部的成員。 * 它與一個例項繫結在了一起,不可以定義靜態的屬性和方法 * */ public class Outter1 { static int a = 1; int b = 0; public static void test1() { System.out.println("外部類的靜態方法"); } public void test2() { System.out.println("外部類的非靜態方法"); } class Inner { // static String aa; // 不可以定義靜態的屬性和方法 public void test() { System.out.println("在成員內部類的方法中"); test1();// 呼叫外部類的靜態方法 test2();// 呼叫外部類的非靜態方法 System.out.println("訪問外部類的靜態成員變數和非靜態成員變數:" + (a + b));// 訪問外部類的靜態成員變數和非靜態成員變數 } } public static void main(String[] args) { // Inner in = new Inner(); // 成員內部類的物件不能直接建立,編譯會報錯 Outter1 out = new Outter1(); // 先建立外部類的物件 Inner in = out.new Inner(); // 注意:!成員內部類的物件必須通過外部類的物件建立 in.test(); // 呼叫內部類的方法 } }
/**
* 區域性內部類只能在方法內部中使用,一旦方法執行完畢,區域性內部類就會從記憶體中刪除。
必須注意:如果區域性內部類中要使用他所在方法中的區域性變數,那麼就需要將這個區域性變數定義為final的。
*
*/
public class Outter2 {
int a = 10;
public void test() {
final int c = 5;
System.out.println("執行外部類的方法");
class Inner {
int b = 20;
void test1() {
System.out.println("執行區域性內部類的方法,b:" + b);
/**
* 注意:如果區域性內部類中要使用他所在方法中的區域性變數,
* 那麼就需要將這個區域性變數定義為final的。
*/
System.out.println("呼叫方法的區域性變數final,c:" + c);
}
}
Inner inner = new Inner();
inner.test1();
}
public static void main(String[] args) {
Outter2 outter = new Outter2();
outter.test();
}
}
/**
* 匿名內部類的定義與物件的建立合併在一起,匿名內部類一般通過如下形式定義,並且在定義的同時進行物件的例項化。
new 類或者介面的名字(){
//匿名內部類的主體,大括號中是匿名內部類的主體,這個主體就是類或者介面的實現,
* 如果是類,那麼匿名內部類是該類的子類,
* 如果是介面,匿名內部類需要完成介面的實現。
}
*
*/
public class Outter3 {
public static void main(String[] args) {
Person person = new Person();
person.show(new Message() {
public void show() {
System.out.println("在匿名內部類中");
}
});
// 比較經典的建立執行緒的一種方式
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("new Thread");// 輸出:new Thread 2
}
});
t2.start();
}
}
class Person {
public void show(Message message) {
message.show();
}
}
class Message {
public void show() {
System.out.println("在Message類中");
}
}
// 測試通過內部類實現多繼承等
class Example1 {
public String name() {
return "Example1 name()";
}
}
class Example2 {
public int age() {
return 1;
}
}
class Example3 {
public int age() {
return 1;
}
}
class InnerExtendExample {
private String id = "id";
private static String name = "name";
//一般的非內部類,是不允許有 private 與protected許可權的,
// 但內部類可以,所以我們能通過內部類來隱藏我們的資訊。
private class test1 extends Example1 {
public String name() {
System.out.println("呼叫外部類的成員變數,id:" + id);
System.out.println("呼叫外部類的靜態變數,name:" + name);
return super.name();
}
}
private class test2 extends Example2 {
public int age() {
return super.age();
}
}
public String name() {
return new test1().name();
}
public int age() {
return new test2().age();
}
public static void main(String args[]) {
InnerExtendExample ie = new InnerExtendExample();
System.out.println("獲得父類Example1的方法,姓名:" + ie.name() );
System.out.println("獲得父類Example2的方法,年齡:" + ie.age());
}
}