内部类总结

  • 定义:指在一个外部类的内部再定义一个类。
  1.  内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。
  2. 内部类可以对同一个包中的其他类隐藏起来。
  3. 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。
  4. 内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以和外部类的相同。

 

  • 使用内部类访问对象状态

  内部类可以是静态static的,也可用public,default,protected和private修饰,而常规的类只能具有包的可见性(default),或公有的可见性(public)。

  内部类的对象有一个隐式引用(这个引用在内部类的定义中是不可见的),它引用了实例化该内部类对象的外围类对象。通过这个指针,可以访问外围类对象的全部状态。

  所以,内部类既可以访问自身的数据域,也可以访问创建它的外围类对象的数据域。

  •  内部类的特殊语法规则

  使用外围类引用的正规语法:

  OuterClass.this

  可以采用下列语法格式更加明确地编写内部对象的构造器:

  OuterObject.new InnerClass(construction parameters)

  在外围类的作用域之外,可以这样引用内部类:

  OuterClass.InnerClass

 

  • Java中内部类共分为四种

静态/嵌套内部类 static inner class (also called nested class)

成员内部类 member inner class

局部内部类 local inner class

匿名内部类 anonymous inner class

 


 

 

静态/嵌套内部类 static inner class (also called nested class)

  1. 最简单的内部类形式。
  2. 类定义时加上static关键字。不需要内部类对象和外部类对象之间的联系,可直接引用outer.inner,即不需要创建外部类,也不需要创建内部类。
  3. 不能和外部类有相同的名字。
  4. 只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。
  5. 嵌套类和普通的内部类还有一个区别:普通内部类不能有static数据和static属性,也不能包含嵌套类,但嵌套类可以。而嵌套类不能声明为private,一般声明为public,方便调用。
  6. 注意,声明在接口中的内部类自动成为public和static。

 

声明静态内部类对象的方式为:

OuterClass.InnerClass inner = new OuterClass.InnerClass();

 

 1 public class StaticInner {
 2     static int a=1;
 3     int b=2;
 4     /*  也可在外部类里生成内部类对象:
 5      * StaticInner.Inner inner = new StaticInner.Inner();
 6      */
 7     //定义一个内部类
 8     public static class  Inner{
 9         int a = 3;
10         int b = 4;
11         public void display(){
12             System.out.println(a);//此时调用Inner类中的a
13             System.out.println(StaticInner.a);//此时调用StaticInner类中的a
14             System.out.println(b);//此时调用Inner类中的b
15         }
16     }
17     
18     public static void main(String[] args) {
19         /*  声明静态内部类对象的方式为
20          * OuterClass.InnerClass name = new OuterClass.InnerClass();
21          */
22         StaticInner.Inner inner = new StaticInner.Inner();
23         inner.display();
24     }
25 
26 }
点击查看代码

 

3
1
4
点击查看运行结果

 

 


 

成员内部类Member Inner Class

  1. 定义时不用static修饰,成员内部类就像一个实例变量。
  2. 成员内部类不能含有static的变量和方法,因为成员内部类需要先创建了外部类,才能创建它自己的。
  3. 可直接使用外部类的所有变量和方法,不管是静态的还是非静态的都可以,即使是private的。
  4. 外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取。

 

在外部类里面创建成员内部类的实例:

this.new Innerclass();

在外部类之外创建内部类的实例:

(new Outerclass()).new Innerclass();

在内部类里访问外部类的成员:                         访问外部类static成员:

Outerclass.this.member                           Outerclass.member

 1 public class Outer {
 2     int a=0;
 3     int b=1;
 4     
 5     Inner inner = this.new Inner();// 在外部类里面创建成员内部类的实例
 6     
 7     //定义一个内部类
 8     public class Inner{
 9         int a = 2;
10         public void display(){
11             System.out.println(b);//直接访问外部类对象
12             System.out.println(Outer.this.a);// 访问外部类成员
13             
14             System.out.println(a);// 访问内部类成员
15             System.out.println(this.a);// 访问内部类成员
16         }
17     }
18     
19     public static void main(String[] args) {
20         /*在外部类之外创建内部类的实例:
21           Outer.Inner inner = new Outer().new Inner();
22         */
23         Outer outer = new Outer();
24         outer.inner.display();
25     }
26 
27 }
点击查看代码
1
0
2
2
点击查看运行结果

 

 

 


 

局部内部类Local Inner Class

  1. 局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。
  2. 像局部变量一样,不能被public, protected, private和static修饰。
  3. 只能访问方法中定义的final类型的局部变量,对它进行初始化后不能够再修改。
  4. 局部类的一个优势即对外部世界可以完全地隐藏起来。
  5. 局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。
 1 class LocalInner
 2 {
 3     int a = 1;
 4 
 5     public void doSomething()
 6     {
 7         int b = 2;
 8         final int c = 3;
 9         // 定义一个局部内部类
10         class Inner3
11         {
12             public void test()
13             {
14                 System.out.println("Hello World");
15                 System.out.println(a);
16 
17                 // 不可以访问非final的局部变量
18                 // error: Cannot refer to a non-final variable b inside an inner
19                 // class defined in a different method
20                 // System.out.println(b);
21 
22                 // 可以访问final变量
23                 System.out.println(c);
24             }
25         }
26 
27         // 创建局部内部类的实例并调用方法
28         new Inner3().test();
29     }
30 }
31 
32 public class LocalInnerClassTest
33 {
34     public static void main(String[] args)
35     {
36         // 创建外部类对象
37         LocalInner inner = new LocalInner();
38         // 调用外部类的方法
39         inner.doSomething();
40     }
41 
42 }
43 
44 点击查看代码
点击查看代码
Hello World
1
3
点击查看运行结果

 


 

匿名内部类Anonymous Inner Class

  1. 假如只创建这个类的一个对象,就不必为它命名了,这种没有名字的局部内部类被称为匿名内部类。

     通常的语法格式为:

      new SuperType(construction parameters)

      {

             inner class methods and data

      }

     SuperType可以是类也可以是接口,匿名内部类隐式地继承了一个父类或者实现了一个接口。

  2. 不能加访问修饰符,不使用关键字class, extends, implements。
  3. 由于构造器的名字必须和类名相同,而匿名类没有类名,所以匿名类不能有构造器。
  4. 匿名内部类中使用的外部局部变量是final变量。
  5. 匿名内部类使用得比较多,通常是作为一个方法参数。
 1 import java.util.Date;
 2 
 3 public class AnonymouseInnerClass
 4 {
 5 
 6     @SuppressWarnings("deprecation")
 7     public String getDate(Date date)
 8     {
 9         return date.toLocaleString();
10 
11     }
12 
13     public static void main(String[] args)
14     {
15         AnonymouseInnerClass test = new AnonymouseInnerClass();
16 
17         // 打印日期:
18         String str = test.getDate(new Date());
19         System.out.println(str);
20         System.out.println("----------------");
21 
22         // 使用匿名内部类
23         String str2 = test.getDate(new Date()
24         {
25         });// 使用了花括号,但是不填入内容,执行结果和上面的完全一致
26             // 生成了一个继承了Date类的子类的对象
27         System.out.println(str2);
28         System.out.println("----------------");
29 
30         // 使用匿名内部类,并且重写父类中的方法
31         String str3 = test.getDate(new Date()
32         {
33 
34             // 重写父类中的方法
35             @Override
36             @Deprecated
37             public String toLocaleString()
38             {
39                 return "Hello: " + super.toLocaleString();
40             }
41 
42         });
43 
44         System.out.println(str3);
45     }
46 }
点击查看代码

 生成的.class文件中,匿名类会生成OuterClass$1.class文件,数字根据是第几个匿名类而类推。

 

 


 

 

参考网站:

http://android.blog.51cto.com/268543/384844/

http://www.cnblogs.com/mengdd/archive/2013/02/08/2909307.html

 

posted @ 2015-07-29 18:17  JonthanJ  阅读(145)  评论(0)    收藏  举报