将用一些例子来阐述各种类型内部类的使用场景以及优势(与top-level-classes enclose-class相比)
分类 内部类即classes within classes.在Java中有两种类型的类,即top-level-classes(classed defined directly within a package)和nested classes(classes defined within top-level-classes). 优点 1. help grouping the related functionlity together. 如果A类仅仅被B类使用,很明显,A类是不必要声明为top-level-classes的,此时A类作为内部类的好处是:减少混乱、增加可读性。(reduce clutter and increase readability) 2. nested classes is able to access all the class members of their enclosing top-level-class(including the private members and variables).这比传统使用实例来访问非private变量和方法有效得多(如例子一);在事件驱动的程序中,这个优势更加明显。 3. 内部类与子类的区别,或者说内部类的优势之一是内部类可以访问顶层类的私有成员,而子类不行,除非父类成员用protected声明。
例子一
//使用实例来访问非私有成员或函数 public class A{ public Integer a; public void print(){ System.out.println("Foobar"); } } public class Main{ public static void main(String[] args){ System.out.println(new A().a); new A().print(); } }不同嵌套类之间有一些细微差别。
作为top-level-classes: 不能访问内部类的成员. 作为nested classes: 可以直接访问顶层类的所有成员(包括私有成员)。 嵌套类所处位置:可以是任意块。只是在块内不能有修饰词:private/public/protected
public class Outer { private class Inner1{ } public class Inner2{} protected class Inner3{} class Inner4{} //普通块 { class Inner5{ } } //静态块 static{ class Inner6{ } } //方法内部 public void method1(){ class Inner7{} } }这是使用最广泛的一种。唯一限制的条件是:内部类中不能有static声明
public class OuterClass { private int private_member_variable = 100; // show如何定义内部类 public class InnerClass { public void printPrivateVariable() { //访问顶层类的内部成员很便利 System.out.println(private_member_variable); } } //【在顶层类内部】如何获取内部类的实例 public void callInnerClassMethod() { InnerClass innerClass = new InnerClass(); innerClass.printPrivateVariable(); } public static void main(String args[]) { OuterClass outerClass = new OuterClass(); outerClass.callInnerClassMethod(); } }在顶层类外部如何获取内部类的实例?
public class TestClass { public static void main(String args[]) { OuterClass outerClass = new OuterClass(); //注意语法 OuterClass.InnerClass innerClass = outerClass.new InnerClass(); innerClass.printPrivateVariable(); } }匿名内部类和普通内部类的唯一区别是匿名,即没有名字
public class code3 { public static void main(String[] args) { /**public Thread(Runnable target), new Runnable(){xxx}就是一个匿名内部类*/ Thread thread = new Thread(new Runnable() { public void run() { System.out.println("i'm anonymous classes"); } }); thread.start(); } }使用时机: when an object instance are required on the fly (fly感觉是享元模式,轻量型的意思) 以何种方式: 继承类,或者实现类
语法 1. new Interface to implement . 如上个例子。 2. abstract/concrete class to extend () {body of the anonymous class to be defined};
静态嵌套类与顶层类是隔绝的,即与非静态内部类相反,静态嵌套类不能【直接访问】顶层类的成员。原因是静态成员,静态类成员仅能直接访问静态成员。可以通过顶层类的object instance访问顶层类的成员。
public class OuterClass { private int private_member_variable = 100; //静态嵌套类的定义 public static class StaticInnerClass { public void printPrivateVariables() { OuterClass outerClass = new OuterClass(); //访问顶层类的成员是通过顶层类的object instance System.out.println(outerClass.private_member_variable); } } public static void main(String args[]) { //静态嵌套类和一般的顶层类是一样的 StaticInnerClass staticInnerClass = new StaticInnerClass(); staticInnerClass.printPrivateVariables(); } }顶层类外部是如何实例化静态嵌套类的
public class Test { public static void main(String args[]) { OuterClass.StaticInnerClass staticInnerClass = new OuterClass.StaticInnerClass(); staticInnerClass.printPrivateVariables(); } }A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.
嵌套类、内部类、内置类都是同一种意思,栗子如下
class OuterClass { ... class NestedClass { ... } }内部类有4种风味: 1. static nested classes 2. inner classes 3. method local inner classes 4. anonymous inner classe
可进一步划分为两大类 1. static: Nested classes that are declared static are called static nested classes. 2. non-static : Non-static nested classes are called inner classes.
上述2、3、4就是非静态的内部类。
优点: 1. 更能体现Java语言的封装特性。设top-class为b,a为其内部类。a可以访问b的成员(函数,变量),a声明为private,可以对外隐藏自己。 2. more readable and maintainable。把被使用到的代码(内部类)放置在离调用方更近的地方。 3. 当只在一处使用某些代码,使用内部类对组织类有好处(包组织更合理化)。 4. 更能体现Java语言的面向对象特性.
参考
【1】http://www.javaworld.com/article/2075984/java-language/introduction-to-nested-classes-in-java.html 【2】https://www.tutorialspoint.com/java/java_innerclasses.htm 【3】https://www.cis.upenn.edu/~bcpierce/courses/629/jdkdocs/guide/innerclasses/spec/innerclasses.doc.html 【4】http://www.javaworld.com/article/2077411/core-java/inner-classes.html 【5】https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html