java-内部类

重新来认识一下内部类的区别

1 Static member class(静态成员类)
类声明中包含“static”关键字的内部类。如以下示例代码,
Inner1/Inner2/Inner3/Inner4就是Outer的四个静态成员类。静态成员类的使用方式与一般顶层类的使用方式基本相同。

public class  Outer{
   
//
just like static method, static member class has public/private/default access privilege levels
   
   
//access privilege level: public

    public static class Inner1 {
       
public
Inner1() {
           
//Static member inner class can access static method of outer class

            staticMethod();   
           
//
Compile error: static member inner class can not access instance method of outer class
           
//instanceMethod(); 

        }
    }
   
   
//access privilege level: default

    static class Inner2 {
       
    }
   
   
//access privilege level: private

    private static class Inner3 {
       
//define a nested inner class in another inner class

        public static class Inner4 {   
        }
    }

   
private static void
staticMethod() {
       
//cannot define an inner class in a method

        /*public static class Inner4() {
        }
*/

    }
   
   
private void instanceMethod() {
       
//private static member class can be accessed only in its outer class definition scope

        Inner3 inner3 = new Inner3();
       
//how to use nested inner class

        Inner3.Inner4 inner4 = new Inner3.Inner4();
    }
}

class
Test {
    Outer.Inner1 inner1
= new
Outer.Inner1();
   
//Test and Outer are in the same package, so Inner2 can be accessed here

    Outer.Inner2 inner2 = new Outer.Inner2();
   
//
Compile error: Inner3 cannot be accessed here
   
//Outer.Inner3 inner3 = new Outer.Inner3();

}
1.1      静态成员类特性

静态成员类可访问外部类的任一静态字段或静态方法

像静态方法或静态字段一样,静态成员类有public/private/default权限修饰符

1.2      静态成员类约束

静态成员类不能与外部类重名

像外部类的静态方法一样,不能直接访问外部类的实例字段和实例方法

静态成员类只能定义于外部类的顶层代码或外部类其它静态成员类的顶层代码中(嵌套定义);不能定义于外部类的某个函数中。

1.3      新增语法
    如示例代码所示,可以以“OuterClass.InnerClass”的方式来引用某个内部类。
1.4      什么时候使用静态成员类
B为A的辅助类,且只为A所用时,可将B定义为A的静态成员类。例如JDK中的LinkedList类就有Entry静态成员类:
public class LinkedList<E> extends AbstractSequentialList<E>
   …;
  
private static class Entry<E>
{
    E element;
    Entry
<E>
next;
    Entry
<E>
previous;

    Entry(E element, Entry
<E> next, Entry<E>
previous) {
       
this.element =
element;
       
this.next =
next;
       
this.previous =
previous;
    }
    }
    …;
}

 

显然,Entry用来表示LinkedList中的一个结点,只被LinkedList自身使用。


2          Member class(成员类)
 
一个静态成员类,若去掉“static”关键字,就成为成员类。如下示例代码,Inner1/Inner2/Inner3/Inner4就是Outer的四个成员类
public class Outer {
   
//just like instance method, member class has public/private/default access privilege levels

    private int data;
   
   
//access privilege level: public

    public class Inner1 {
       
private int
data;
       
private int
data1;
       
public
Inner1() {
           
//member class can access its outer class' instance field directly

            data1 = 1;
           
//itself data field

            data = 1;
           
//its outer class instance field

            Outer.this.data = 1;
        }
    }
   
   
//access privilege level: default

    class Inner2 {
       
//
can not define static filed, method, class in member class
       
//
static int j = 1;
       
       
//but, "static final" compound is allowed

        static final int CONSTANT = 1;
    }
   
   
//access privilege level: private

    private class Inner3 {
       
public class
Inner4 {
           
        }
    }
   
   
//in fact, Inner5 is not a member class but a static member class

    interface Inner5 {
    }
   
   
private static void
staticMethod() {
       
//
can not create a member class instance directly in outer class' static method
       
//Inner1 inner1 = new Inner1();

    }
   
   
private void
instanceMethod() {
       
//can create a member class instance in outer class' instance method

        Inner1 inner1 = new Inner1();
    }
}

class
Test {
   
public
Test() {
       
//
cannot create member class instance directly in class other than outer class
       
//
Outer.Inner2 inner2 = new Outer.Inner2();
       
       
//create a member class instance outside it's outer class

        Outer outer = new Outer();
        Outer.Inner1 inner1
= outer.new
Inner1();
    }
}
2.1      成员类特性
·        类似于外部类的实例函数,成员类有public/private/default权限修饰符
·        一个成员类实例必然所属一个外部类实例,成员类可访问外部类的任一个实例字段和实例函数。
2.2      成员类约束

成员类不能与外部类重名

不能在成员类中定义static字段、方法和类(static final形式的常量定义除外)。因为一个成员类实例必然与一个外部类实例关联,这个static定义完全可以移到其外部类中去

成员类不能是接口(interface)。因为成员类必须能被某个外部类实例实例化,而接口是不能实例化的。事实上,如示例代码所示,如果你以成员 类的形式定义一个接口,该接口实际上是一个静态成员类,static关键字对inner interface是内含(implicit)的。

2.3      新增语法
    一个成员类实例必然所属于其外部类的一个实例,那么如何在成员类内部获得其所属外部类实例呢?如示例代码所示,采用“OuterClass.this”的形式。
2.4      指定内部类实例所属的外部类实例
内部类实例可在其外部类的实例方法中创建,此新创建内部类实例所属的外
部类实例自然就是创建它的外部类实例方法对应的外部类实例。
          另外,如示例代码所示,对于给定的一个外部类实例outerClass,可以直接创建其内部类实例,语法形式为:
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
 

2.5      什么时候使用成员类
     成员类的显著特性就是成员类能访问它的外部类实例的任意字段与方法。方便一个类对外提供一个公共接口的实现是成员类的典型应用。
       以JDK Collection类库为例,每种Collection类必须提供一个与其对应的Iterator实现以便客户端能以统一的方式遍历任一Collection实例。每种Collection类的Iterator实现就被定义为该Collection类的成员类。例如JDK中AbstractList类的代码片断:
2.5      什么时候使用成员类
     成员类的显著特性就是成员类能访问它的外部类实例的任意字段与方法。方便一个类对外提供一个公共接口的实现是成员类的典型应用。
       以JDK Collection类库为例,每种Collection类必须提供一个与其对应的Iterator实现以便客户端能以统一的方式遍历任一Collection实例。每种Collection类的Iterator实现就被定义为该Collection类的成员类。例如JDK中AbstractList类的代码片断:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
   
private class Itr implements Iterator<E>
{
         ………;
    }

    
public Iterator<E>
iterator() {
       
return new
Itr();
     }
}
 

因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。
   试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例 成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。

3          Local class(局部类)
对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类
的静态方法或静态初始化代码段中就成为了局部静态成员类。
       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。
       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。
       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。
另外,局部类也有其自己的特性,如以下代码所示:

因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。
   试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例 成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。

3          Local class(局部类)
对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类
的静态方法或静态初始化代码段中就成为了局部静态成员类。
       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。
       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。
       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。
另外,局部类也有其自己的特性,如以下代码所示:

因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。
   试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例 成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。

3          Local class(局部类)
对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类
的静态方法或静态初始化代码段中就成为了局部静态成员类。
       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。
       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。
       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。
另外,局部类也有其自己的特性,如以下代码所示:

因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。
   试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例 成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。

3          Local class(局部类)
对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类
的静态方法或静态初始化代码段中就成为了局部静态成员类。
       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。
       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。
       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。
另外,局部类也有其自己的特性,如以下代码所示:

因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。
   试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例 成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。

3          Local class(局部类)
对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类
的静态方法或静态初始化代码段中就成为了局部静态成员类。
       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。
       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。
       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。
另外,局部类也有其自己的特性,如以下代码所示:

因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。
   试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例 成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。

3          Local class(局部类)
对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类
的静态方法或静态初始化代码段中就成为了局部静态成员类。
       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。
       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。
       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。
另外,局部类也有其自己的特性,如以下代码所示:

因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。
   试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例 成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。

3          Local class(局部类)
对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类
的静态方法或静态初始化代码段中就成为了局部静态成员类。
       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。
       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。
       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。
另外,局部类也有其自己的特性,如以下代码所示:

因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。
   试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例 成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。

3          Local class(局部类)
对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类
的静态方法或静态初始化代码段中就成为了局部静态成员类。
       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。
       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。
       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。
另外,局部类也有其自己的特性,如以下代码所示:

因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。
   试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例 成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。

3          Local class(局部类)
对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类
的静态方法或静态初始化代码段中就成为了局部静态成员类。
       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。
       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。
       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。
另外,局部类也有其自己的特性,如以下代码所示:

因为定义在AbstractList中的Itr可访问AbstractList中的任意字段和方法,所以很方便实现Iterator,无需AbstractList对外暴露更多的接口。
   试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例 成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。

3          Local class(局部类)
对一个静态成员类,去掉其声明中的“static”关键字,将其定义移入其外部类
的静态方法或静态初始化代码段中就成为了局部静态成员类。
       对一个成员类,将其定义移入其外部类的实例方法或实例初始化代码中就成为了局部成员类。
       局部静态成员类与静态成员类的基本特性相同。例如,都只能访问外部类的静态字段或方法,但不能访问外部类的实例字段和实例方法等。
       局部成员类与成员类的基本特性相同。例如,局部成员类实例必属于其外部类的一个实例,可通过OuterClass.this引用其外部类实例等。
另外,局部类也有其自己的特性,如以下代码所示:

public class Outer {
   
private int instanceField;
   
private static int staticField;
   
   
//define a local member class in instance code block
    {
       
int localVirable1 = 0;
       
final int localVirable2 = 1;
       
class Inner1 {
           
public Inner1() {
               
//can access its outer class' field and method directly
                instanceField = 1;
               
//use OuterClass.this to get its corresponding outer class instance
                Outer.this.instanceField = 1;
               
               
//can not access the not final local virable in its containing code block
               
//System.out.print(localVirable1);
               
               
//can access the final local virable in its containing code block
                System.out.print(localVirable2);
            }
        }       
       
       
//local class can not have privilege modifier
        /*public class inner2 {           
        }
*/
    }
   
   
// define a local static member class in static code block
    static {
       
class Inner2 {
           
public Inner2() {
                staticField
= 1;
               
//can not access instance field and method in a local static member class
               
//intanceField = 2;
            }
        }
    }
   
   
public void intanceMethod() {
       
//define a local class in its out class' instance method
        class Inner3 {
        }
       
       
//local class is visible only in its containning code block
       
//Outer.Inner2 inner2;
    }
   
   
private static void staticMethod() {
       
//define a local static member class in its out class' static method
        class Inner4 {   
           
public Inner4() {
                staticField
= 2;
            }
        }
       
       
//can not define a interface as a local class
        /*interface I {
        }
*/
    }
}
 
 
public class Outer {
   
private int
instanceField;
   
private static int
staticField;
   
   
//define a local member class in instance code block

    {
       
int localVirable1 = 0
;
       
final int localVirable2 = 1
;
       
class
Inner1 {
           
public
Inner1() {
               
//can access its outer class' field and method directly

                instanceField = 1;
               
//use OuterClass.this to get its corresponding outer class instance

                Outer.this.instanceField = 1;
               
               
//
can not access the not final local virable in its containing code block
               
//
System.out.print(localVirable1);
               
               
//can access the final local virable in its containing code block

                System.out.print(localVirable2);
            }
        }       
       
       
//local class can not have privilege modifier

        /*public class inner2 {           
        }
*/

    }
   
   
// define a local static member class in static code block
    static {
       
class
Inner2 {
           
public
Inner2() {
                staticField
= 1
;
               
//
can not access instance field and method in a local static member class
               
//intanceField = 2;

            }
        }
    }
   
   
public void
intanceMethod() {
       
//define a local class in its out class' instance method

        class Inner3 {
        }
       
       
//
local class is visible only in its containning code block
       
//Outer.Inner2 inner2;

    }
   
   
private static void
staticMethod() {
       
//define a local static member class in its out class' static method

        class Inner4 {   
           
public
Inner4() {
                staticField
= 2
;
            }
        }
       
       
//can not define a interface as a local class

        /*interface I {
        }
*/

    }
}

 

 

3.1      局部类特性
如示例代码所示,局部类能且只能访问其所属代码段中的声明为final的局部
变量。为什么只能访问声明为final的局部变量呢?我们知道,局部变量在其所属的代码段(譬如某个函数)执行完毕后就会被回收,而一个局部类 的实例却可以在其类定义所属代码段执行完毕后依然存在,如果它可操控非final的局部变量,用户就可以通过该实例修改已不存在的局部变量,无意义。
3.2      局部类约束

如示例代码所示,内部类只在定义它的代码段中可见,不能在它所属代码段之外的代码中使用;因此也就没有public/private/default权限修饰符(无意义)

不能以局部类形式定义一个接口。局部类只在其所属代码段中可见,定义这样的接口无意义

局部类类名不能与其外部类类名重复

3.3      什么时候使用局部类
局部类大部分以匿名类的形式使用。
           
4          Anonymous class(匿名类)
没有类名的局部类就是匿名类。用一条语句完成匿名类的定义与实例创建。例
 

public class Outer {
   
public void
instanceMethod() {
       
//define a nonymous class which implements Action interface and creat an instance of it

        Action action = new Action() {
           
public void
doAction() {
                System.out.println(
"a simple anonymous class demo"
);
            }};
        action.doAction();
       
       
//define a nonoymous class which extends BaseClass and create an instance of it

        new BaseClass(5) {
           
public void
printData(){
                System.out.println(
"data = " +
getData());
            }
        }.printData();
//"data = 5" will be outputed

    }
}

interface
Action {
   
void
doAction();
}

class
BaseClass {
   
private int
data;
   
   
public BaseClass (int
data) {
       
this.data =
data;
    }
   
   
public int
getData() {
       
return
data;
    }
}

 

4.1      匿名类特性与约束
匿名类是一种特殊的局部类。局部类的特性与约束都适用与它。
匿名内部类可以继承其他类,因为是类就是继承自Object类的。
所谓的匿名就是该类连名字都没有,匿名内部类不可以有构造器,因为匿名内部类是要扩展或实现父类或接口
在一个方法的匿名内部类,可以利用这个方法传进你想要的参数,不过记住,这些参数必须被声明为final。
4.2      新增语法
4.2.1      继承自某个基类的匿名类


 

new class-name ( [ argument-list ] ) { class-body }
创建匿名类实例时,“argument-list”将被传入其基类(即class-name)对应的构造函数。
4.2.2      实现某个接口的匿名类

 

new interface-name () { class-body }

4.3      什么时候使用匿名类

该类定义代码段很短

只需要创建该类的一个实例

类的定义代码与类的使用代码紧邻

使用匿名不影响代码的易读性

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值