Java學習(十六)、成員內部類,靜態內部類,匿名內部類,局部內部類,java靜態
定義:將一個類定義在另一個類的內部。內部的類稱為內部類;
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