定義:將一個類定義在另一個類的內部。內部的類稱為內部類;
public class Outer{
class inner{
//省略
}
}
特點:
① 內部類可以很好的實現隱藏,可以使用protected,private修飾符;
② 內部類可以直接訪問外部類的所有成員,包括私有成員;
③ 外部類不能直接訪問內部類的成員,必須首先要建立內部類的對象才能訪問;
④ 內部類可以解決一些問題,比如間接的去實現多繼承。可以避免修改接口而實現同一個類中兩種同名方法的調用;
成員內部類及應用
成員內部類特點:
① 成員內部類屬於外部類的實例成員,成員內部類都可以有public,private,default,protected權限修飾符。在成員內部類中訪問外部類的成員方法和屬性,要使用“外部類名.this.成員方法”和“外部類名.this.成員屬性”的形式;
② 創建成員內部類的實例使用“外部類名.內部類名.實例名=外部類實例名. new 內部類構造方法(參數)”的形式;
成員內部類有以下限制
① 成員內部類不能與外部類重名;
② 不能在成員內部類中定義static屬性、方法和類(static,final形式的常量定義除外)。因為一個成員內部類實例必然與一個外部類實例關聯,static成員完全可移到其外部類中去;
1 public class MemberInnerClass{ 2 public static void main(String []args){ 3 //創建外部類對象 4 Outer1 outer=new Outer1(); 5 //創建內部類對象 6 Outer1.Inner1 inner=outer.new Inner1(); 7 inner.innerShow(); 8 9 System.out.println("--------------外部類訪問內部類對象--------------"); 10 outer.outerShow(); 11 } 12 } 13 14 class Outer1{ 15 private String name="張三"; 16 private int num1=10; 17 public void outerShow(){ 18 System.out.println(name); 19 System.out.println(num1); 20 //System.out.println(num2);//外部類不能直接訪問內部類的成員 21 22 //外部類訪問內部類對象 23 Inner1 inner =new Inner1(); 24 inner.innerShow(); 25 } 26 27 //當內部類改成私有時private,僅能在外部類中訪問 28 public class Inner1{ 29 private String name="李四"; 30 private int num2=20; 31 private static final int num3=30;//靜態常量在內部類中是可以使用的 32 //private static int num3=30;//在成員內部類中不能聲明靜態成員和靜態方法 33 public void innerShow(){ 34 System.out.println(name); 35 System.out.println(num2); 36 37 //成員內部類可以直接訪問外部類的屬性和方法,包括私有的 38 System.out.println("--------------"); 39 //外部類訪問內部類時注釋outerShow(),避免死循環 40 //outerShow(); 41 42 //打印外部類中成員屬性 43 System.out.println("--------------打印外部類中成員屬性--------------"); 44 System.out.println(Outer1.this.name); 45 System.out.println(Outer1.this.num1); 46 } 47 } 48 } View Code用內部類間接實現多繼承
1 public class MultiExtendsDemo{ 2 public static void main(String []args){ 3 C c=new C(); 4 //間接實現多繼承 5 c.showA(); 6 c.showB(); 7 } 8 } 9 10 class A{ 11 public void showA(){ 12 System.out.println("A"); 13 } 14 } 15 16 class B{ 17 public void showB(){ 18 System.out.println("B"); 19 } 20 } 21 22 class C{ 23 private class A1 extends A{ 24 public void showA(){ 25 super.showA(); 26 } 27 } 28 29 private class B1 extends B{ 30 public void showB(){ 31 super.showB(); 32 } 33 } 34 35 public void showA(){ 36 new A1().showA(); 37 } 38 39 public void showB(){ 40 new B1().showB(); 41 } 42 } View Code父類中和接口中的方法名相同
為了不更改其方法且要實現這個2個方法
采用內部類的方式來實現
1 public class Demo2{ 2 public static void main(String []args){ 3 Son son=new Son(); 4 son.show(); 5 son.show2(); 6 } 7 } 8 9 abstract class Parent{ 10 public abstract void show(); 11 } 12 13 interface IShow{ 14 public abstract void show(); 15 } 16 17 /*class Son extends Parent implements IShow{ 18 public void show(){ 19 20 } 21 public void show1(){ 22 23 } 24 }*/ 25 26 //因為父類中和接口中的方法名相同 27 //為了不更改其方法且要實現這個2個方法 28 //采用內部類的方式來實現 29 //但最好的方式還是改方法 30 class Son extends Parent{ 31 public void show(){ 32 System.out.println("抽象類中的show方法"); 33 } 34 35 private class Inner2 implements IShow{ 36 public void show(){ 37 System.out.println("接口中的show方法"); 38 } 39 } 40 41 public void show2(){ 42 Inner2 inner=new Inner2(); 43 inner.show(); 44 } 45 } View Code
靜態內部類及其應用
靜態內部類特點:
① 使用static修飾的成員內部類叫靜態內部類;
② 靜態內部類跟外部類沒有任何關系,只是在生成類名和類定義時有影響。靜態內部類可以看作是與外部類平級的類。使用方式與外部類平級的類完全相同;
③ 創建靜態內部類的實例使用 外部類名.內部類名. 實例名=new 外部類名.內部類名(參數);
靜態內部類有以下限制:
① 靜態內部類的名字不能與外部相同;
② 靜態內部類不能訪問外部類的非靜態的屬性和方法,外部類不能訪問內部類的非靜態的屬性和方法;
1 public class StaticInnerClass{ 2 public static void main(String []args){ 3 Outer2.Inner2 inner=new Outer2.Inner2();//構造一個靜態內部類對象 4 inner.innerShow(); 5 6 Outer2 outer=new Outer2(); 7 outer.outerShow(); 8 } 9 } 10 11 class Outer2{ 12 private String name="張三"; 13 private int num1=10; 14 private static int num3=100; 15 public void outerShow(){ 16 System.out.println(name); 17 System.out.println(num1); 18 19 //System.out.println(Inner2.name); 20 Inner2 inner =new Inner2(); 21 System.out.println(inner.name);//訪問非靜態 22 23 System.out.println(Inner2.num3);//訪問靜態 24 } 25 26 public static class Inner2{ 27 private String name="李四"; 28 private int num2=20; 29 private static final int num3=30; 30 31 public void innerShow(){ 32 System.out.println(name); 33 System.out.println(num2); 34 35 //System.out.println(Outer2.this.name);//靜態內部類不能訪問外部類的非靜態成員 36 System.out.println(Outer2.num3); 37 System.out.println(num2); 38 } 39 } 40 } View Code
匿名內部類及應用
匿名內部類特點:
① 匿名內部類時沒有名稱的內部類,沒辦法引用它們。必須在創建時,作為new語句的一部分來聲明並創建它們的實例;
② 匿名內部類必須繼承一個類(抽象的,非抽象的都可以)或者實現一個接口。如果父類(或父接口)是抽象類,則匿名內部類必須實現其所有抽象方法;
③ 匿名內部類中可以定義代碼塊,用於實例的初始化,但是不能定義靜態代碼塊;
匿名內部類的語法:new interface/superclass(){//類體}
這種形式的new語句聲明一個新的匿名類,它對一個給定的類進行擴展,或者實現一個給定的接口,並同時創建該匿名類的一個新實例;
不使用匿名內部類時
1 public class AnonymousInnerClass{ 2 public static void main(String []args){ 3 Person person=new Person(); 4 Animal dog=new Dog(); 5 person.feed(dog); 6 } 7 } 8 9 abstract class Animal{ 10 public abstract void eat(); 11 } 12 13 class Person{ 14 public void feed(Animal animal){ 15 animal.eat(); 16 } 17 } 18 19 class Dog extends Animal{ 20 public void eat(){ 21 System.out.println("啃骨頭"); 22 } 23 } View Code使用匿名內部類
1 public class AnonymousInnerClass{ 2 public static void main(String []args){ 3 Person person=new Person(); 4 //Animal dog=new Dog(); 5 //person.feed(dog); 6 7 /*Animal dog=*/new IAnimal(){ 8 private String name="aa"; 9 10 //代碼塊 11 { 12 name="哈哈"; 13 } 14 15 //不能使用靜態代碼塊 16 //static{} 17 public void eat(){ 18 System.out.println("啃骨頭"); 19 } 20 public void show(){ 21 System.out.println(name); 22 } 23 }.show();//調用內部的show(); 24 25 //person.feed(dog); 26 //dog.show();//這裡不能調用定義的show(); 27 //person.feed(dog); 28 person.feed(new IAnimal(){ 29 public void eat(){ 30 System.out.println("吃魚"); 31 } 32 }); 33 } 34 } 35 36 //抽象類 37 //使用接口時先注釋 38 //並修改Person類中的Animal為IAnimal 39 /*abstract class Animal{ 40 public abstract void eat(); 41 }*/ 42 43 //接口 44 interface IAnimal{ 45 public abstract void eat(); 46 } 47 48 class Person{ 49 public void feed(IAnimal animal){ 50 animal.eat(); 51 } 52 } 53 54 /*class Dog extends Animal{ 55 public void eat(){ 56 System.out.println("啃骨頭"); 57 } 58 }*/ View Code局部內部類及應用
局部內部類的特點:
① 定義在代碼塊、方法體內的類叫局部內部類;
② 局部內部類訪問外部類的屬性和方法使用“外部類名.this.屬性名”和“外部類名.this.方法名(參數)”的形式;
③ 對外部世界完全隱藏,只能在其作用域內生成對象;
局部內部類有以下限制:
① 局部內部類不能加訪問修飾符,因為它們不能類成員;
② 成員內部類不能與外部類重名;
③ 局部內部類訪問作用域內的局部變量,該局部變量需要使用final修飾;
1 public class LocalInnerClass{ 2 public static void main(String []args){ 3 Outer3 outer=new Outer3(); 4 outer.showOuter(); 5 } 6 } 7 8 class Outer3{ 9 private String name="張三"; 10 private int num1=10; 11 private static int num2=20; 12 public void showOuter(){ 13 /*final*/ int num4=50;//這裡加不加final都可以被內部類訪問?希望看到的且知道的幫我解答下 14 //局部內部類不能加訪問修飾符 15 class Inner3{ 16 private int num3=30; 17 private int num1=20; 18 public void showInner(){ 19 System.out.println(num3); 20 System.out.println(num1); 21 22 System.out.println(Outer3.this.num1); 23 System.out.println(Outer3.num2); 24 25 System.out.println(num4); 26 } 27 } 28 Inner3 inner=new Inner3(); 29 inner.showInner(); 30 } 31 } View Code