码迷,mamicode.com
首页 > 编程语言 > 详细

Java知多少(37)静态内部类、匿名内部类、成员式内部类和局部内部类

时间:2015-04-17 01:01:32      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:

内部类可以是静态(static)的,可以使用 public、protected 和 private 访问控制符,而外部类只能使用 public,或者默认。

成员式内部类

在外部类内部直接定义(不在方法内部或代码块内部)的类就是成员式内部类,它可以直接使用外部类的所有变量和方法,即使是 private 的。外部类要想访问内部类的成员变量和方法,则需要通过内部类的对象来获取。

请看下面的代码:
 1 public class Outer{
 2     private int size;
 3     public class Inner {
 4         public void dostuff() {
 5             size++;
 6         }
 7     }
 8     public void testTheInner() {
 9         Inner in = new Inner();
10         in.dostuff();
11     }
12 }
成员式内部类如同外部类的一个普通成员。

成员式内部类可以使用各种修饰符,包括 public、protected、private、static、final 和 abstract,也可以不写。

若有 static 修饰符,就为类级,否则为对象级。类级可以通过外部类直接访问,对象级需要先生成外部的对象后才能访问。

非静态内部类中不能声明任何 static 成员。

内部类可以相互调用,例如:

成员式内部类的访问

1 class A {
2     // B、C 间可以互相调用
3     class B {}
4     class C {}
5 }
内部类的对象以成员变量的方式记录其所依赖的外层类对象的引用,因而可以找到该外层类对象并访问其成员。该成员变量是系统自动为非 static 的内部类添加的,名称约定为“outClassName.this”。

1) 使用内部类中定义的非静态变量和方法时,要先创建外部类的对象,再由“outObjectName.new”操作符创建内部类的对象,再调用内部类的方法,如下所示:
 1 public class Demo{
 2     public static void main(String[] args) {
 3         Outer outer = new Outer();
 4         Outer.Inner inner = outer.new Inner();
 5         inner.dostuff();
 6     }
 7 }
 8 class Outer{
 9     private int size;
10     class Inner{
11         public void dostuff() {
12             size++;
13         }
14     }
15 }
2) static 内部类相当于其外部类的 static 成员,它的对象与外部类对象间不存在依赖关系,因此可直接创建。示例如下:
 1 public class Demo{
 2     public static void main(String[] args) {
 3         Outer.Inner inner = new Outer.Inner();
 4         inner.dostuff();
 5     }
 6 }
 7 class Outer{
 8     private static int size;
 9     static class Inner {
10         public void dostuff() {
11             size++;
12             System.out.println("size=" + size);
13         }
14     }
15 }
运行结果:
size=1

3) 由于内部类可以直接访问其外部类的成分,因此当内部类与其外部类中存在同名属性或方法时,也将导致命名冲突。所以在多层调用时要指明,如下所示:
 1 public class Outer{
 2     private int size;
 3     public class Inner{
 4         private int size;
 5         public void dostuff(int size){
 6             size++;  // 局部变量 size;
 7             this.size;  // 内部类的 size
 8             Outer.this.size++;  // 外部类的 size
 9         }
10     }
11 }

局部内部类

局部内部类(Local class)是定义在代码块中的类。它们只在定义它们的代码块中是可见的。

局部类有几个重要特性:
  1. 仅在定义了它们的代码块中是可见的;
  2. 可以使用定义它们的代码块中的任何局部 final 变量;
  3. 局部类不可以是 static 的,里边也不能定义 static 成员;
  4. 局部类不可以用 public、private、protected 修饰,只能使用缺省的;
  5. 局部类可以是 abstract 的。

请看下面的代码:
 1 public class Outer {
 2     public static final int TOTAL_NUMBER = 5;
 3     public int id = 123;
 4     public void func() {
 5         final int age = 15;
 6         String str = "http://www.weixueyuan.net";
 7         class Inner {
 8             public void innerTest() {
 9                 System.out.println(TOTAL_NUMBER);
10                 System.out.println(id);
11                 // System.out.println(str);不合法,只能访问本地方法的final变量
12                 System.out.println(age);
13             }
14         }
15         new Inner().innerTest();
16     }
17     public static void main(String[] args) {
18         Outer outer = new Outer();
19         outer.func();
20     }
21 }

 


运行结果:
5
123
15

匿名内部类

匿名内部类是局部内部类的一种特殊形式,也就是没有变量名指向这个类的实例,而且具体的类实现会写在这个内部类里面。

注意:匿名类必须继承一个父类或实现一个接口。

不使用匿名内部类来实现抽象方法:
 1 abstract class Person {
 2     public abstract void eat();
 3 }
 4 class Child extends Person {
 5     public void eat() {
 6         System.out.println("eat something");
 7     }
 8 }
 9 public class Demo {
10     public static void main(String[] args) {
11         Person p = new Child();
12         p.eat();
13     }
14 }
运行结果:
eat something

可以看到,我们用Child继承了Person类,然后实现了Child的一个实例,将其向上转型为Person类的引用。但是,如果此处的Child类只使用一次,那么将其编写为独立的一个类岂不是很麻烦?

这个时候就引入了匿名内部类。使用匿名内部类实现:
 1 abstract class Person {
 2     public abstract void eat();
 3 }
 4 public class Demo {
 5     public static void main(String[] args){
 6        
 7         // 继承 Person 类
 8         new Person() {
 9             public void eat() {
10                 System.out.println("eat something");
11             }
12         }.eat();
13     }
14 }

可以看到,匿名类继承了 Person 类并在大括号中实现了抽象类的方法。

内部类的语法比较复杂,实际开发中也较少用到,本教程不打算进行深入讲解,各位读者也不应该将内部类作为学习Java的重点。

系列文章:

Java知多少(1)语言概述

Java知多少(2)虚拟机(JVM)以及跨平台原理

Java知多少(3) 就业方向

Java知多少(4)J2SE、J2EE、J2ME的区别

Java知多少(5) Java开发环境的搭建

Java知多少(6)第一个程序示例

Java知多少(7)类与对象

Java知多少(8)类库及其组织结构

Java知多少(9) import及Java类的搜索路径

Java知多少(10)数据类型及变量

Java知多少(11)数据类型转换

Java知多少(12)运算符

Java知多少(13)流程控制

Java知多少(14)数组

Java知多少(15)字符串

Java知多少(16)StringBuffer与StringBuider

Java知多少(17)强调一下编程风格

Java知多少(18)类的定义及其实例化

Java知多少(19)访问修饰符(访问控制符)

Java知多少(20)变量的作用域

Java知多少(21)this关键字详解

Java知多少(22)方法重载

Java知多少(23)类的基本运行顺序

Java知多少(24)包装类、拆箱和装箱详解

Java知多少(25)再谈Java包

Java知多少(26)源文件的声明规则

Java知多少(27)继承的概念与实现

Java知多少(28)super关键字

Java知多少(29)覆盖和重载

Java知多少(30)多态和动态绑定

Java知多少(31)static关键字以及Java静态变量和静态方法

Java知多少(32)instanceof

Java知多少(33)多态对象的类型转换

Java知多少(34)final关键字:阻止继承和多态

Java知多少(35)Object类

Java知多少(36)内部类及其实例化

Java知多少(37)静态内部类、匿名内部类、成员式内部类和局部内部类

Java知多少(37)静态内部类、匿名内部类、成员式内部类和局部内部类

标签:

原文地址:http://www.cnblogs.com/Coda/p/4433627.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!